Tk Source Code

Changes On Branch tip529-image-metadata-no-match-method
Login

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

Changes In Branch tip529-image-metadata-no-match-method Excluding Merge-Ins

This is equivalent to a diff from 3f7fb3f1 to 80d02564

2021-02-27
15:22
Merge TIP 529 to trunk check-in: 790e32e7 user: kevin_walzer tags: trunk, main
2021-02-25
14:04
Fix reference of tests Closed-Leaf check-in: 80d02564 user: fvogel tags: tip529-image-metadata-no-match-method
2021-02-07
12:41
Remove superfluous .AS call in CrtPhImgFmt.3, and fix typos and indentation. check-in: 69ad6ea2 user: fvogel tags: tip529-image-metadata-no-match-method
2021-01-23
12:15
Branch [tip529-image-metadata-no-match-method] to back out match method check-in: cdedc5da user: oehhar tags: tip529-image-metadata-no-match-method
2020-06-29
09:17
Merge trunk check-in: ae527714 user: jan.nijtmans tags: tip-529-image-metadata
2020-06-28
16:11
Merge tip-529-image-metadata check-in: 087616ef user: jan.nijtmans tags: tip-529-image-metadata-optional
15:56
Merge trunk check-in: 3f7fb3f1 user: jan.nijtmans tags: tip-529-image-metadata
15:39
Merge 8.6 check-in: 7312d4e0 user: jan.nijtmans tags: trunk
2020-06-26
10:42
Make C++ compiler more happy (for Travis build) check-in: 4f5da4e9 user: jan.nijtmans tags: tip-529-image-metadata

Changes to .fossil-settings/encoding-glob.

1
2

3





1
2
3
4
5
6
7
8
9


+

+
+
+
+
+
win/buildall.vc.bat
win/makefile.vc
win/rules-ext.vc
win/rules.vc
win/targets.vc
win/rc/*.bmp
win/rc/*.cur
win/rc/*.ico
win/rc/*.rc

Changes to .fossil-settings/ignore-glob.

1
2
3

4
5
6
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
37



+




















+
+
+
+
+






-
+
+
*.a
*.dll
*.dylib
*.dylib.E
*.exe
*.exp
*.la
*.lib
*.lo
*.o
*.obj
*.pdb
*.res
*.sl
*.so
*/Makefile
*/autom4te.cache
*/config.cache
*/config.log
*/config.status
*/tkConfig.sh
*/wish*
*/tktest*
*/versions.vc
*/version.vc
*/libtk.vfs
*/libtk_*.zip
html
macosx/configure
win/Debug*
win/Release*
win/*.manifest
win/nmhlp-out.txt
win/nmakehlp.out
unix/tk.pc
html/*
unix/Tk-Info.plist
unix/Wish-Info.plist

Changes to .gitattributes.

18
19
20
21
22
23
24

25
26
27
28
29


30
31
32
33

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







+





+
+




+






*.svg text
*.ts text
*.tcl text
*.test text

# Declare files that will always have CRLF line endings on checkout.
*.bat eol=crlf
*.rc eol=crlf
*.sln eol=crlf
*.vc eol=crlf

# Denote all files that are truly binary and should not be modified.
*.a binary
*.bmp binary
*.cur binary
*.dll binary
*.exe binary
*.gif binary
*.gz binary
*.ico binary
*.jpg binary
*.lib binary
*.pdf binary
*.png binary
*.xlsx binary
*.zip binary

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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
name: Linux
on: [push]
defaults:
  run:
    shell: bash
    working-directory: tk/unix
env:
  ERROR_ON_FAILURES: 1
jobs:
  build:
    runs-on: ubuntu-20.04
    strategy:
      matrix:
        compiler:
          - "gcc"
          - "clang"
        cfgopt:
          - ""
          - "CFLAGS=-DTK_NO_DEPRECATED=1"
          - "--disable-shared"
          - "--disable-xft"
          - "--disable-xss"
          - "--enable-symbols"
    steps:
      - name: Checkout
        uses: actions/checkout@v2
        with:
          path: tk
      - name: Checkout Tcl
        uses: actions/checkout@v2
        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
          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.cfgopt }}
          COMPILER: ${{ matrix.compiler }}
          OPTS: ${{ matrix.compiler }}${{ matrix.cfgopt }}
      - name: Configure (opts=${{ matrix.cfgopt }})
        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@v2
        with:
          name: Tk ${{ env.VERSION }} Source distribution (unofficial)
          path: |
            /tmp/dist/tk*
            !/tmp/dist/tk*/html/**
      - name: Upload Documentation Distribution
        if: ${{ env.BUILD_CONFIG_ID == 'gcc' }}
        uses: actions/upload-artifact@v2
        with:
          name: Tk ${{ env.VERSION }} HTML documentation (unofficial)
          path: /tmp/dist/tk*/html
  test:
    runs-on: ubuntu-20.04
    strategy:
      matrix:
        compiler:
          - "gcc"
        cfgopt:
          - ""
          - "--enable-symbols"
    steps:
      - name: Checkout
        uses: actions/checkout@v2
        with:
          path: tk
      - name: Setup Environment (compiler=${{ matrix.compiler }})
        run: |
          sudo apt-get install tcl8.6-dev libxss-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.cfgopt }}
          COMPILER: ${{ matrix.compiler }}
      - name: Configure ${{ matrix.cfgopt }}
        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
          }

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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
name: macOS
on: [push]
env:
  ERROR_ON_FAILURES: 1
jobs:
  xcode:
    runs-on: macos-11.0
    defaults:
      run:
        shell: bash
        working-directory: tk/macosx
    steps:
      - name: Check out Tk
        uses: actions/checkout@v2
        with:
          path: tk
      - name: Check out Tcl
        uses: actions/checkout@v2
        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
          }
  clang:
    runs-on: macos-11.0
    strategy:
      matrix:
        symbols:
          - 'no'
          - 'mem'
        options:
          - '--enable-aqua'
          - '--disable-aqua'
    defaults:
      run:
        shell: bash
        working-directory: tk/unix
    steps:
      - name: Check out Tk
        uses: actions/checkout@v2
        with:
          path: tk
      - name: Check out Tcl
        uses: actions/checkout@v2
        with:
          repository: tcltk/tcl
          ref: core-8-6-branch
          path: tcl
      - name: Prepare checked out repositories
        run: |
          touch tkStubInit.c
          mkdir "$HOME/install dir"
          echo "USE_XVFB=$SET_DISPLAY" >> $GITHUB_ENV
        working-directory: tk/generic
        env:
          SET_DISPLAY: ${{ contains(matrix.options, '--disable-aqua') }}
      - name: Add X11 (if required)
        if: ${{ env.USE_XVFB }}
        # This involves black magic
        run: |
          brew install --cask xquartz
          sudo /opt/X11/lib/X11/xinit/privileged_startx.d/10-tmpdirs || 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" || {
            cat config.log
            echo "::error::Failure during Configure"
            exit 1
          }
        env:
          CFGOPT: --enable-symbols=${{ matrix.symbols }} ${{matrix.options }}
      - name: Build
        run: |
          make all 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 {
              : do nothing
            }
          fi
          ( runXvfb :0; make test-classic; exit $? ) | tee out-classic.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
          ( runXvfb :0; make test-ttk; exit $? ) | tee out-ttk.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
          cat out-classic.txt out-ttk.txt | grep -q "Failed[[:space:]][[:space:]]*[1-9]" && {
            echo "::error::Failure during Test"
            exit 1
          }
        env:
          MAC_CI: 1
      - name: Carry out trial installation
        run: |
          make install || {
            cat config.log
            echo "::error::Failure during Install"
            exit 1
          }

Added .github/workflows/onefiledist.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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
name: Build Binaries
on: [push]
jobs:
  linux:
    name: Linux
    runs-on: ubuntu-16.04
    defaults:
      run:
        shell: bash
    env:
      CC: gcc
      CFGOPT: --disable-symbols --disable-shared
    steps:
      - name: Checkout Tk
        uses: actions/checkout@v2
        with:
          path: tk
      - name: Checkout Tcl 8.7
        uses: actions/checkout@v2
        with:
          repository: tcltk/tcl
          ref: core-8-branch
          path: tcl
      - name: Setup Environment
        run: |
          sudo apt-get install libxss-dev
          mkdir -p install/1dist.vfs
          touch tcl/generic/tclStubInit.c tcl/generic/tclOOStubInit.c
          touch tk/generic/tkStubInit.c
          echo "INST_DIR=$(cd install;pwd)" >> $GITHUB_ENV
          echo "VER_PATH=$(cd tcl/tools; pwd)/addVerToFile.tcl" >> $GITHUB_ENV
        working-directory: "."
      - name: Configure Tcl
        run: |
          ./configure $CFGOPT --enable-zipfs --prefix=$INST_DIR
        working-directory: tcl/unix
      - name: Build & Install Tcl
        run: |
          make binaries libraries tclzipfile install
          make shell SCRIPT="$VER_PATH $GITHUB_ENV"
        working-directory: tcl/unix
      - name: Configure Tk
        run: |
          ./configure $CFGOPT --with-tcl=$INST_DIR/lib --prefix=$INST_DIR
        working-directory: tk/unix
      - name: Build & Install Tk
        run: |
          make binaries libraries install
        working-directory: tk/unix
        # TODO: need the Tk version separately for distro naming below
      - name: Pack Tk Library Files into Library Zip
        run: |
          unzip ../lib/libtcl*.zip
          cp -a ../lib/tk[0-9]* .
          zip -r ../1dist.zip .
        working-directory: ${{ env.INST_DIR }}/1dist.vfs
      - name: Package
        run: |
          cat ../tk/unix/wish 1dist.zip >> ${BUILD_NAME}
          chmod +x ${BUILD_NAME}
          tar -cf ${BUILD_NAME}.tar ${BUILD_NAME}
        working-directory: ${{ env.INST_DIR }}
        env:
          BUILD_NAME: wish${{ env.TCL_PATCHLEVEL }}_unofficial
      - name: Upload
        uses: actions/upload-artifact@v2
        with:
          name: Wish ${{ env.TCL_PATCHLEVEL }} Linux single-file build (unofficial)
          path: ${{ env.INST_DIR }}/*.tar
      - name: Describe Installation Zip Contents
        if: ${{ always() }}
        run: |
          unzip -l 1dist.zip || true
        working-directory: ${{ env.INST_DIR }}
  macos:
    name: macOS
    runs-on: macos-11.0
    defaults:
      run:
        shell: bash
    env:
      CC: gcc
      CFGOPT: --disable-symbols --disable-shared --enable-64bit
    steps:
      - name: Checkout Tk
        uses: actions/checkout@v2
        with:
          path: tk
      - name: Checkout Tcl 8.7
        uses: actions/checkout@v2
        with:
          repository: tcltk/tcl
          ref: core-8-branch
          path: tcl
      - name: Checkout create-dmg
        uses: actions/checkout@v2
        with:
          repository: create-dmg/create-dmg
          ref: v1.0.8
          path: create-dmg
      - name: Setup Environment
        run: |
          mkdir -p install/1dist.vfs install/contents
          touch tcl/generic/tclStubInit.c tcl/generic/tclOOStubInit.c
          touch tk/generic/tkStubInit.c
          echo "INST_DIR=$(cd install;pwd)" >> $GITHUB_ENV
          echo "VER_PATH=$(cd tcl/tools; pwd)/addVerToFile.tcl" >> $GITHUB_ENV
          echo "CREATE_DMG=$(cd create-dmg;pwd)/create-dmg" >> $GITHUB_ENV
        working-directory: "."
      - name: Configure Tcl
        run: |
          ./configure $CFGOPT --enable-zipfs --prefix=$INST_DIR
        working-directory: tcl/unix
      - name: Build & Install Tcl
        run: |
          make binaries libraries tclzipfile install
          make shell SCRIPT="$VER_PATH $GITHUB_ENV"
        working-directory: tcl/unix
      - name: Configure Tk
        run: |
          ./configure $CFGOPT --with-tcl=$INST_DIR/lib --prefix=$INST_DIR \
              --enable-aqua
        working-directory: tk/unix
      - name: Build & Install Tk
        run: |
          make binaries libraries install
        working-directory: tk/unix
        # TODO: need the Tk version separately for distro naming below
      - name: Pack Tk Library Files into Library Zip
        run: |
          unzip ../lib/libtcl*.zip
          cp -a ../lib/tk[0-9]* .
          zip -r ../1dist.zip .
        working-directory: ${{ env.INST_DIR }}/1dist.vfs
      - name: Package
        run: |
          cat ../tk/unix/wish 1dist.zip >> contents/${BUILD_NAME}
          chmod +x contents/${BUILD_NAME}
          cat > contents/README.txt <<EOF
          This is a single-file executable developer preview of Tcl/Tk $TCL_PATCHLEVEL

          It is not intended as an official release at all, so it is unsigned and unnotarized.
          Use strictly at your own risk.

          To run it, you need to copy the executable out and run:
              xattr -d com.apple.quarantine ${BUILD_NAME}
          to mark the executable as runnable on your machine.
          EOF
          $CREATE_DMG \
              --volname "TclTk $TCL_PATCHLEVEL (unofficial)" \
              --window-pos 200 120 \
              --window-size 800 400 \
              "TclTk-$TCL_PATCHLEVEL-(unofficial).dmg" \
              "contents/"
        working-directory: ${{ env.INST_DIR }}
        env:
          BUILD_NAME: wish${{ env.TCL_PATCHLEVEL }}_unofficial
      - name: Upload
        uses: actions/upload-artifact@v2
        with:
          name: Wish ${{ env.TCL_PATCHLEVEL }} macOS single-file build (unofficial)
          path: ${{ env.INST_DIR }}/*.dmg
  win:
    name: Windows
    runs-on: windows-latest
    defaults:
      run:
        shell: bash
    env:
      CC: gcc
      CFGOPT: --disable-symbols --disable-shared
    steps:
      - name: Checkout Tk
        uses: actions/checkout@v2
        with:
          path: tk
      - name: Checkout Tcl 8.7
        uses: actions/checkout@v2
        with:
          repository: tcltk/tcl
          ref: core-8-branch
          path: tcl
      - name: Setup Environment
        run: |
          mkdir -p install/1dist
          mkdir -p install/combined
          touch tcl/generic/tclStubInit.c tcl/generic/tclOOStubInit.c
          touch tk/generic/tkStubInit.c
          echo "INST_DIR=$(cd install;pwd)" >> $GITHUB_ENV
          echo "VER_PATH=$(cd tcl/tools; pwd)/addVerToFile.tcl" >> $GITHUB_ENV
        working-directory: "."
      - name: Configure Tcl
        run: |
          ./configure $CFGOPT --enable-zipfs --prefix=$INST_DIR
        working-directory: tcl/win
      - name: Build & Install Tcl
        run: |
          make binaries libraries tclzipfile install
          echo "ZIP_BIN=`pwd`/minizip.exe" >> $GITHUB_ENV
          echo "TCL_ZIP=`pwd`/`echo libtcl*.zip`" >> $GITHUB_ENV
          $INST_DIR/bin/tclsh* $VER_PATH $GITHUB_ENV
        working-directory: tcl/win
      - name: Configure Tk
        run: |
          ./configure $CFGOPT --with-tcl=$INST_DIR/lib --prefix=$INST_DIR
        working-directory: tk/win
      - name: Build & Install Tk
        run: |
          make all install
          echo "TK_BIN=`pwd`/`echo wish*.exe`" >> $GITHUB_ENV
        working-directory: tk/win
        # TODO: need the Tk version separately for distro naming below
      - name: Pack Tk Library Files into Library Zip
        run: |
          unzip $TCL_ZIP
          cp -R ../lib/tk[0-9]* .
          $ZIP_BIN -o -r ../1dist.zip *
        working-directory: install/1dist
      - name: Package
        run: |
          cat ${TK_BIN} 1dist.zip > combined/${BUILD_NAME}.exe
        working-directory: install
        env:
          BUILD_NAME: wish${{ env.TCL_PATCHLEVEL }}_unofficial
      - name: Upload
        uses: actions/upload-artifact@v2
        with:
          name: Wish ${{ env.TCL_PATCHLEVEL }} Windows single-file build (unofficial)
          path: install/combined/wish${{ env.TCL_PATCHLEVEL }}_unofficial.exe

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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
name: Windows
on: [push]
env:
  ERROR_ON_FAILURES: 1
jobs:
  msvc:
    runs-on: windows-2019
    defaults:
      run:
        shell: powershell
        working-directory: tk/win
    # Using powershell means we need to explicitly stop on failure
    steps:
      - name: Checkout
        uses: actions/checkout@v2
        with:
          path: tk
      - name: Checkout
        uses: actions/checkout@v2
        with:
          repository: tcltk/tcl
          ref: core-8-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
        run: |
          &nmake -f makefile.vc release install
          if ($lastexitcode -ne 0) {
             throw "nmake exit code: $lastexitcode"
          }
        working-directory: tcl/win
      - name: Build
        run: |
          &nmake -f makefile.vc all
          if ($lastexitcode -ne 0) {
             throw "nmake exit code: $lastexitcode"
          }
      - name: Build Test Harness
        run: |
          &nmake -f makefile.vc tktest
          if ($lastexitcode -ne 0) {
             throw "nmake exit code: $lastexitcode"
          }
      - name: Run Tests
        run: |
          nmake -f makefile.vc test-classic | tee out-classic.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
          nmake -f makefile.vc test-ttk | 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
      - name: Build Help
        run: |
          &nmake -f makefile.vc htmlhelp
          if ($lastexitcode -ne 0) {
             throw "nmake exit code: $lastexitcode"
          }
      - name: Install
        run: |
          &nmake -f makefile.vc install
          if ($lastexitcode -ne 0) {
             throw "nmake exit code: $lastexitcode"
          }
  gcc:
    runs-on: windows-2019
    defaults:
      run:
        shell: bash
        working-directory: win
    strategy:
      matrix:
        symbols:
          - "no"
          - "mem"
          - "all"
    # Using powershell means we need to explicitly stop on failure
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Checkout
        uses: actions/checkout@v2
        with:
          repository: tcltk/tcl
          ref: core-8-6-branch
          path: tcl
      - name: Install MSYS2, Make
        run: choco install -y msys2 make
      - 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
        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 --enable-symbols=${{ matrix.symbols }}
        working-directory: tcl/win
      - name: Configure (symbols=${{ matrix.symbols }})
        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 --enable-symbols=${{ matrix.symbols }}
      - name: Build
        run: |
          make all tktest || {
            echo "::error::Failure during Build"
            exit 1
          }
      - name: Run 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
          }

Changes to .gitignore.

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




+












+







*.a
*.bundle
*.dll
*.dylib
*.dylib.E
*.exe
*.exp
*.lib
*.o
*.obj
*.pdb
*.res
*.sl
*.so
.fslckout
Makefile
Tk-Info.plist
Wish-Info.plist
autom4te.cache
config.cache
config.log
config.status
config.status.lineno
html
manifest.uuid
51
52
53
54
55
56
57
58
59

53
54
55
56
57
58
59

60
61







-

+
unix/autoMkindex.tcl
unix/dltest.marker
unix/tk.pc
unix/tclIndex
win/Debug*
win/Release*
win/*.manifest
win/nmhlp-out.txt
win/nmakehlp.out
win/nmhlp-out.txt

Changes to .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

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

14
15
16
17
18
19
20
21
22
23
24


25
26


27
28

29
30
31

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

49
50
51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

104
105
106
107
108
109
110

111
112
113
114
115
116
117

118
119
120
121
122
123
124

125
126
127
128
129


130
131
132


133
134
135
136


137

138












139
140
141
142
143
144
145
146


147
148
149
150

151
152
153

154
155
156
157
158
159

160
161
162
163
164
165
166

167
168
169
170
171
172
173

174
175
176
177
178
179
180

181
182
183
184
185
186

187
188

189
190
191
192

193
194

195
196
197
198

199
200

201










202
203
204




205
206

207
208
209
210









211
212
213
214
215
216



217

218
219

220
221
222
223
224
225
226



227
228
229



230
231
232
233
234




235
236
237
238
239
240
241
242
243
244
245



246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261

262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278


279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
-



+
+








-
+

+
+
+
+



+
+
-
-
+
+
-
-
+

-
+


-
+
+
+



+
+
+
+
+
+
+
+
+


-
+
+
+




+


-
+
+
+




+
-
+

+
+
+
+
+
+
+
+
+
+

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






-
+






-
+






-
+






-
+




-
-
+
+

-
-
+
+


-
-

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








-
-




-
+


-
+





-
+






-
+






-
+






-
+





-
+

-
+



-
+

-
+



-
+

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



-
-
-
-
+

-
+



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

-
+

-
+



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



-
-
-
-
+


+
+
+
+
+



-
-
-
















-
+
















-
-



+
+
+
+
+
+
+


+


sudo: required
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
      - tcl-dev
      - tcl8.6-dev
      - libx11-dev
      - libnotify-dev
      - libglib2.0-dev
      - libxss-dev
      - xvfb
  homebrew:
    packages:
      - tcl-tk
      - libnotify
      - glib
    casks:
      - xquartz
#   casks:
#     - xquartz
    update: true
matrix:
jobs:
  include:
# Testing on Linux with various compilers
# Testing on Linux GCC
    - name: "Linux/GCC/Shared"
      os: linux
      dist: bionic
      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: bionic
      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: bionic
      dist: focal
      services:
        - xvfb
      compiler: gcc
      env:
        - BUILD_DIR=unix
        - CFGOPT="--disable-xft"
      script: *x11gui
    - name: "Linux/GCC/Static"
    - name: "Linux/GCC/Shared/no-libnotify"
      os: linux
      dist: focal
      services:
        - xvfb
      compiler: gcc
      env:
        - BUILD_DIR=unix
        - CFGOPT="--disable-libnotify"
      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: bionic
      dist: focal
      compiler: gcc
      env:
        - BUILD_DIR=unix
        - CFGOPT="--enable-symbols"
    - name: "Linux/G++/Shared"
      os: linux
      dist: bionic
      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: bionic
      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: bionic
      dist: focal
      compiler: g++
      env:
        - BUILD_DIR=unix
        - CFGOPT="CC=g++ CFLAGS=-DTCL_UTF_MAX=6"
# Older versions of GCC...
    - name: "Linux/GCC 7/Shared"
# Newer/Older versions of GCC
    - name: "Linux/GCC 10/Shared"
      os: linux
      dist: bionic
      compiler: gcc-7
      dist: focal
      compiler: gcc-10
      addons:
        apt:
          sources:
            - ubuntu-toolchain-r-test
          packages:
            - g++-7
            - g++-10
      env:
        - BUILD_DIR=unix
    - name: "Linux/GCC 6/Shared"
      os: linux
      dist: bionic
      compiler: gcc-6
      addons:
        apt:
          sources:
            - ubuntu-toolchain-r-test
          packages:
            - g++-6
      env:
        - BUILD_DIR=unix
    - name: "Linux/GCC 5/Shared"
      os: linux
      dist: bionic
      compiler: gcc-5
      addons:
        apt:
          sources:
            - ubuntu-toolchain-r-test
          packages:
            - g++-5
      env:
        - BUILD_DIR=unix
# Clang
# Testing on Linux Clang
    - name: "Linux/Clang/Shared"
      os: linux
      dist: bionic
      dist: focal
      compiler: clang
      env:
        - BUILD_DIR=unix
    - name: "Linux/Clang/Shared: NO_DEPRECATED"
      os: linux
      dist: bionic
      dist: focal
      compiler: clang
      env:
        - BUILD_DIR=unix
        - CFGOPT="CFLAGS=-DTK_NO_DEPRECATED=1"
    - name: "Linux/Clang/Shared/no-xft"
      os: linux
      dist: bionic
      dist: focal
      compiler: clang
      env:
        - BUILD_DIR=unix
        - CFGOPT="--disable-xft"
    - name: "Linux/Clang/Static"
      os: linux
      dist: bionic
      dist: focal
      compiler: clang
      env:
        - CFGOPT="--disable-shared"
        - BUILD_DIR=unix
    - name: "Linux/Clang/Debug"
      os: linux
      dist: bionic
      dist: focal
      compiler: clang
      env:
        - BUILD_DIR=unix
        - CFGOPT="--enable-symbols"
# Testing on Mac, various styles
    - name: "macOS/Clang/Xcode 11.5/Shared"
    - name: "macOS/Xcode 12/Shared"
      os: osx
      osx_image: xcode11.5
      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 11.5/Shared"
    - name: "macOS/Clang++/Xcode 12/Shared"
      os: osx
      osx_image: xcode11.5
      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/Clang/Xcode 11.5/Shared"
    - name: "macOS/Xcode 12/Static"
      os: osx
      osx_image: xcode11.5
      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/Clang/Xcode 11.5/Static"
      os: osx
      osx_image: xcode11.5
      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/Clang/Xcode 11.5/Debug"
    - name: "macOS/Xcode 12/Debug"
      os: osx
      osx_image: xcode11.5
      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/Clang/Xcode 11.5/Shared/XQuartz"
      os: osx
      osx_image: xcode11.5
      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"
#   - 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/Clang/Xcode 11/Shared"
    - name: "macOS/Xcode 11/Shared"
      os: osx
      osx_image: xcode11
      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"
    - name: "macOS/Xcode 10/Shared"
      os: osx
      osx_image: xcode10.3
      install:
        - ./configure ${CFGOPT} "--prefix=$HOME" || (cat config.log && exit 1)
      script: *mactest
      addons:
        homebrew:
          packages:
    - name: "macOS/Clang/Xcode 10/Shared"
      os: osx
      osx_image: xcode10.3
            - 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/Clang/Xcode 9/Shared"
    - 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: bionic
      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)
before_script:
  - export ERROR_ON_FAILURES=1
script:
  - make all tktest
  - make install
before_cache:
  - |-
      case $TRAVIS_OS_NAME in
        osx)
          brew cleanup
          ;;
      esac
cache:
  directories:
  - $HOME/Library/Caches/Homebrew
  - $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  <[email protected]>

	* generic/tkInt.h:	[Bug 3410609]: Change the event mechanism
	* unix/tkUnixEvent.c:	for <KeyPress> events to use the keysym
	* unix/tkUnixEvent.c:	for <Key> 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  <[email protected]>
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  <[email protected]>

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

2008-01-29  Joe English  <[email protected]>

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

2008-01-29  Donal K. Fellows  <[email protected]>

	* 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.2004.

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	 <[email protected]>

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

2003-02-10  Jim Ingham <[email protected]>

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

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

8.6 (production release, daily build)
[![Build Status](https://github.com/tcltk/tk/workflows/Linux/badge.svg?branch=core-8-6-branch)](https://github.com/tcltk/tk/actions?query=workflow%3A%22Linux%22+branch%3Acore-8-6-branch)
[![Build Status](https://github.com/tcltk/tk/workflows/Windows/badge.svg?branch=core-8-6-branch)](https://github.com/tcltk/tk/actions?query=workflow%3A%22Windows%22+branch%3Acore-8-6-branch)
[![Build Status](https://github.com/tcltk/tk/workflows/macOS/badge.svg?branch=core-8-6-branch)](https://github.com/tcltk/tk/actions?query=workflow%3A%22macOS%22+branch%3Acore-8-6-branch)
<br>
8.7 (in development, daily build))
[![Build Status](https://github.com/tcltk/tk/workflows/Linux/badge.svg?branch=main)](https://github.com/tcltk/tk/actions?query=workflow%3A%22Linux%22+branch%3Amain)
[![Build Status](https://github.com/tcltk/tk/workflows/Windows/badge.svg?branch=main)](https://github.com/tcltk/tk/actions?query=workflow%3A%22Windows%22+branch%3Amain)
[![Build Status](https://github.com/tcltk/tk/workflows/macOS/badge.svg?branch=main)](https://github.com/tcltk/tk/actions?query=workflow%3A%22macOS%22+branch%3Amain)

## <a id="intro">1.</a> Introduction

This directory contains the sources and documentation for Tk, a
cross-platform GUI toolkit implemented with the Tcl scripting language.

For details on features, incompatibilities, and potential problems with
this release, see [the Tcl/Tk 8.7 Web page](https://www.tcl.tk/software/tcltk/8.7.html)
or refer to the "changes" file in this directory, which contains a
historical record of all changes to Tk.

Tk is maintained, enhanced, and distributed freely by the Tcl community.
Source code development and tracking of bug reports and feature requests
takes place at [core.tcl-lang.org](https://core.tcl-lang.org/).
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.

329
330
331
332
333
334
335
336

337
338
339
340
341
342
343
329
330
331
332
333
334
335

336
337
338
339
340
341
342
343







-
+







is necessary in order to allow several menu buttons to share the
same menu.
*** POTENTIAL INCOMPATIBILITY ***

4/12/92 (bug fix) Fixed core dump that occurred in tkError.c when
removing the first error record from the error list.

4/15/92 (bug fix) Fixed bug in tkBind.c that prevented <KeyPress-1>
4/15/92 (bug fix) Fixed bug in tkBind.c that prevented <Key-1>
event specifications from being processed correctly:  the "1" was
treated as a button name rather than a keysym.

4/18/92 (new feature) Added Tk_DefineCursor and Tk_UndefineCursor
procedures.

4/18/92 (new feature) Major revision to listboxes.  Can now scroll and
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 master menu is
torn off from, and are deleted when the main menu is
deleted. Tearoffs also reflect more look-and-feel of the
platforms they are running on. (SRP)

10/31/96 (bug fix) Under Windows, missing system cursors would
generate an error instead of falling through to the Tk cursor of the
same name. (SS)

3994
3995
3996
3997
3998
3999
4000
4001

4002
4003
4004
4005
4006
4007
4008
3994
3995
3996
3997
3998
3999
4000

4001
4002
4003
4004
4005
4006
4007
4008







-
+







into account the "-displayof" option.  This problem also existed for the
"font metrics" and "font measure" commands. (CCS)

9/16/97 (new feature) Added "resource delete" and "resource files"
command to the Mac.  Also fixed "resource write" when the resource
was specified by id and already existed. (JI)

9/16/97 (bug fix) Added null bindings to <Command-KeyPress> for the
9/16/97 (bug fix) Added null bindings to <Command-Key> for the
text and entry widget on the Macintosh.  This prevents unbound command
key sequences from having the character echoed to the widget. Also
fixed Cut & Copy bindings.  (JI) (RJ)

9/18/97 (bug fix) Revamped Macintosh focus code.  Cut, Copy & Paste
virtual events now go to the correct (focus) window. (RJ)

7523
7524
7525
7526
7527
7528
7529
7530

7531
7532
7533
7534
7535
7536
7537
7523
7524
7525
7526
7527
7528
7529

7530
7531
7532
7533
7534
7535
7536
7537







-
+








2017-12-31 (bug)[6525e1] encoding leak in tkMacOSXProcessFiles (werner)

2018-01-07 (bug)[925262] New option -state for ttk::scale (vogel)

2018-01-07 (bug)[fa8de7] Crash [ttk::checkbutton .x -variable {}] (werner)

2018-01-16 (bug)[382712] Crash in [event generate . <KeyPress>] (werner)
2018-01-16 (bug)[382712] Crash in [event generate . <Key>] (werner)

2018-01-19 (bug)[657c38] Crash in menu destroy with checkbutton entry (werner)

2018-01-25 (bug)[de156e] Deny PRIMARY selection access in safe interps (nash)

2018-01-28 (bug)[b68710] Fixes in [text] bindings (nash)

7718
7719
7720
7721
7722
7723
7724
















































































































































7725
7726
7727
7728
7729
7730
7731
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







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








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)

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)[40c4bf] 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

Changes to 8.7a3 include all changes to the 8.6 line through 8.6.10,
plus the following, which focuses on the high-level feature changes
in this changeset (new minor version) rather than bug fixes:

2017-11-25 [TIP 161] $menu -tearoff default changed to false (roseman,vogel)
        *** POTENTIAL INCOMPATIBILITY ***

Changes to doc/AddOption.3.

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 Tk_AddOption 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_AddOption \- Add an option to the option database

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











-
+







-
+







'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_CreateImageType 3 8.5 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateImageType, Tk_GetImageMasterData, Tk_InitImageArgs \- define new kind of image
Tk_CreateImageType, Tk_GetImageModelData, Tk_InitImageArgs \- define new kind of image
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateImageType\fR(\fItypePtr\fR)
.sp
ClientData
\fBTk_GetImageMasterData\fR(\fIinterp, name, typePtrPtr\fR)
\fBTk_GetImageModelData\fR(\fIinterp, name, typePtrPtr\fR)
.sp
\fBTk_InitImageArgs\fR(\fIinterp, argc, argvPtr\fR)
.SH ARGUMENTS
.AS "const Tk_ImageType" *typePtrPtr
.AP "const Tk_ImageType" *typePtr in
Structure that defines the new type of image.
For Tk 8.4 and earlier this must be static: a
67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81







-
+







    Tk_ImageDeleteProc *\fIdeleteProc\fR;
} \fBTk_ImageType\fR;
.CE
The fields of this structure will be described in later subsections
of this entry.
.PP
The second major data structure manipulated by an image manager
is called an \fIimage master\fR;  it contains overall information
is called an \fIimage model\fR;  it contains overall information
about a particular image, such as the values of the configuration
options specified in an \fBimage create\fR command.
There will usually be one of these structures for each
invocation of the \fBimage create\fR command.
.PP
The third data structure related to images is an \fIimage instance\fR.
There will usually be one of these structures for each usage of an
109
110
111
112
113
114
115
116
117


118
119
120
121
122
123
124
125
126

127
128
129
130

131
132

133
134

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151

152
153
154
155


156
157
158
159
160
161
162
109
110
111
112
113
114
115


116
117
118
119
120
121
122
123
124
125

126
127
128
129

130
131

132
133

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

151
152
153


154
155
156
157
158
159
160
161
162







-
-
+
+








-
+



-
+

-
+

-
+
















-
+


-
-
+
+







.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_ImageMaster \fImaster\fR,
        ClientData *\fImasterDataPtr\fR);
        Tk_ImageModel \fImodel\fR,
        ClientData *\fImodelDataPtr\fR);
.CE
The \fIinterp\fR argument is the interpreter in which the \fBimage\fR
command was invoked, and \fIname\fR is the name for the new image,
which was either specified explicitly in the \fBimage\fR command
or generated automatically by the \fBimage\fR command.
The \fIobjc\fR and \fIobjv\fR arguments describe all the configuration
options for the new image (everything after the name argument to
\fBimage\fR).
The \fImaster\fR argument is a token that refers to Tk's information
The \fImodel\fR argument is a token that refers to Tk's information
about this image;  the image manager must return this token to
Tk when invoking the \fBTk_ImageChanged\fR procedure.
Typically \fIcreateProc\fR will parse \fIobjc\fR and \fIobjv\fR
and create an image master data structure for the new image.
and create an image model data structure for the new image.
\fIcreateProc\fR may store an arbitrary one-word value at
*\fImasterDataPtr\fR, which will be passed back to the
*\fImodelDataPtr\fR, which will be passed back to the
image manager when other callbacks are invoked.
Typically the value is a pointer to the master data
Typically the value is a pointer to the model data
structure for the image.
.PP
If \fIcreateProc\fR encounters an error, it should leave an error
message in the interpreter result and return \fBTCL_ERROR\fR;  otherwise
it should return \fBTCL_OK\fR.
.PP
\fIcreateProc\fR should call \fBTk_ImageChanged\fR in order to set the
size of the image and request an initial redisplay.
.SS GETPROC
.PP
\fItypePtr->getProc\fR is invoked by Tk whenever a widget
calls \fBTk_GetImage\fR to use a particular image.
This procedure must match the following prototype:
.CS
typedef ClientData \fBTk_ImageGetProc\fR(
        Tk_Window \fItkwin\fR,
        ClientData \fImasterData\fR);
        ClientData \fImodelData\fR);
.CE
The \fItkwin\fR argument identifies the window in which the
image will be used and \fImasterData\fR is the value
returned by \fIcreateProc\fR when the image master was created.
image will be used and \fImodelData\fR is the value
returned by \fIcreateProc\fR when the image model was created.
\fIgetProc\fR will usually create a data structure for the new
instance, including such things as the resources needed to
display the image in the given window.
\fIgetProc\fR returns a one-word token for the instance, which
is typically the address of the instance data structure.
Tk will pass this value back to the image manager when invoking
its \fIdisplayProc\fR and \fIfreeProc\fR procedures.
217
218
219
220
221
222
223
224

225
226
227


228
229
230
231

232
233

234
235

236
237
238
239
240
241
242

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


257
258
259
260
261
262
263
217
218
219
220
221
222
223

224
225


226
227
228
229
230

231
232

233
234

235
236
237
238
239
240
241

242
243
244
245
246
247
248
249
250
251
252
253
254


255
256
257
258
259
260
261
262
263







-
+

-
-
+
+



-
+

-
+

-
+






-
+












-
-
+
+







image is being deleted (i.e. when the \fBimage delete\fR command
is invoked).
Before invoking \fIdeleteProc\fR Tk will invoke \fIfreeProc\fR for
each of the image's instances.
\fIdeleteProc\fR must match the following prototype:
.CS
typedef void \fBTk_ImageDeleteProc\fR(
        ClientData \fImasterData\fR);
        ClientData \fImodelData\fR);
.CE
The \fImasterData\fR argument will be the same as the value
stored in \fI*masterDataPtr\fR by \fIcreateProc\fR when the
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_GETIMAGEMASTERDATA
.SH TK_GETIMAGEMODELDATA
.PP
The procedure \fBTk_GetImageMasterData\fR may be invoked to retrieve
The procedure \fBTk_GetImageModelData\fR may be invoked to retrieve
information about an image.  For example, an image manager can use this
procedure to locate its image master data for an image.
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 master data structure).  If no such image exists
pointer to the image model data structure).  If no such image exists
then NULL is returned and NULL is stored at \fI*typePtrPtr\fR.
.SH "LEGACY INTERFACE SUPPORT"
.PP
In Tk 8.2 and earlier, the definition of \fBTk_ImageCreateProc\fR
was incompatibly different, with the following prototype:
.CS
typedef int \fBTk_ImageCreateProc\fR(
        Tcl_Interp *\fIinterp\fR,
        char *\fIname\fR,
        int \fIargc\fR,
        char **\fIargv\fR,
        Tk_ImageType *\fItypePtr\fR,
        Tk_ImageMaster \fImaster\fR,
        ClientData *\fImasterDataPtr\fR);
        Tk_ImageModel \fImodel\fR,
        ClientData *\fImodelDataPtr\fR);
.CE
Legacy programs and libraries dating from those days may still
contain code that defines extended Tk image types using the old
interface.  The Tk header file will still support this legacy
interface if the code is compiled with the macro \fBUSE_OLD_IMAGE\fR
defined.
.PP
276
277
278
279
280
281
282
283

276
277
278
279
280
281
282

283







-
+
use Tk 8.4 headers and stub libraries to do so.
.PP
Any new code written today should not make use of the legacy
interfaces.  Expect their support to go away in Tk 9.
.SH "SEE ALSO"
Tk_ImageChanged, Tk_GetImage, Tk_FreeImage, Tk_RedrawImage, Tk_SizeOfImage
.SH KEYWORDS
image manager, image type, instance, master
image manager, image type, instance, model

Changes to doc/CrtPhImgFmt.3.

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

13
14
15
16
17
18
19




20
21
22
23





24
25
26
27
28
29

30
31
32
33
34
35
36
37
38
39
40





41
42
43
44
45





46
47

48
49
50
51
52
53
54
55







56

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



72
73
74
75
76
77

78
79
80
81
82
83
84
85


86
87
88

89
90
91

92
93
94
95
96


97
98
99
100
101
102
103
104


105
106
107
108


109
110

111
112
113

114
115
116
117


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

134
135
136
137


138
139
140
141
142
143
144
145
146
147
148
149
150


151
152
153
154
155


156
157
158
159
160
161

162
163
164
165


166
167
168
169
170
171
172
173


174
175
176
177
178


179
180
181
182
183
184
185
186
187
188
189

190
191
192
193
194
195
196
197
198
199
200
201
202
203


204
205
206
207
208



209
210
211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
226
227


228
































































































































































































229
230
231
232
233
234
235
1
2
3
4
5
6
7
8
9
10
11

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

27
28
29
30
31
32
33
34
35
36

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




55
56
57
58
59
60

61
62







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


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

102
103
104
105
106
107
108
109

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


124
125
126
127
128

129
130
131
132
133
134
135

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182


183
184
185
186
187
188
189
190
191
192
193
194

195
196
197
198
199
200
201
202


203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242


243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467











-
+







+
+
+
+



-
+
+
+
+
+





-
+











+
+
+
+
+

-
-
-
-
+
+
+
+
+

-
+

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

+













-
-
+
+
+






+







-
+
+



+


-
+





+
+






-
-
+
+



-
+
+


+


-
+




+
+
















+



-
+
+













+
+



-
-
+
+






+



-
+
+






-
-
+
+





+
+











+














+
+



-
-
+
+
+





+














+
+

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







'\"
'\" Copyright (c) 1994 The Australian National University
'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
'\" Author: Paul Mackerras ([email protected]),
'\"	    Department of Computer Science,
'\"	    Australian National University.
'\"
.TH Tk_CreatePhotoImageFormat 3 8.5 Tk "Tk Library Procedures"
.TH Tk_CreatePhotoImageFormat 3 8.7 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreatePhotoImageFormat \- define new file format for photo images
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
.VS 8.7
\fBTk_CreatePhotoImageFormatVersion3\fR(\fIformatVersion3Ptr\fR)
.VE 8.7
.sp
\fBTk_CreatePhotoImageFormat\fR(\fIformatPtr\fR)
.SH ARGUMENTS
.AS "const Tk_PhotoImageFormat" *formatPtr
.AS "const Tk_PhotoImageFormatVersion3" *formatVersion3Ptr
.VS 8.7
.AP "const Tk_PhotoImageFormatVersion3" *formatVersion3Ptr in
Structure that defines the new file format including metadata functionality.
.VE 8.7
.AP "const Tk_PhotoImageFormat" *formatPtr in
Structure that defines the new file format.
.BE
.SH DESCRIPTION
.PP
\fBTk_CreatePhotoImageFormat\fR is invoked to define a new file format
\fBTk_CreatePhotoImageFormatVersion3\fR is invoked to define a new file format
for image data for use with photo images.  The code that implements an
image file format is called an image file format handler, or
handler for short.  The photo image code
maintains a list of handlers that can be used to read and
write data to or from a file.  Some handlers may also
support reading image data from a string or converting image data to a
string format.
The user can specify which handler to use with the \fB\-format\fR
image configuration option or the \fB\-format\fR option to the
\fBread\fR and \fBwrite\fR photo image subcommands.
.PP
The alternate version 2 function \fBTk_CreatePhotoImageFormat\fR has
identical functionality, but does not allow the handler to get or return
the metadata dictionary of the image.
It is described in section \fBVERSION 2 INTERFACE\fR below.
.PP
An image file format handler consists of a collection of procedures
plus a Tk_PhotoImageFormat structure, which contains the name of the
image file format and pointers to six procedures provided by the
handler to deal with files and strings in this format.  The
Tk_PhotoImageFormat structure contains the following fields:
plus a \fBTk_PhotoImageFormatVersion3\fR structure, which contains the
name of the image file format and pointers to six procedures provided
by the handler to deal with files and strings in this format.  The
Tk_PhotoImageFormatVersion3 structure contains the following fields:
.VS 8.7
.CS
typedef struct Tk_PhotoImageFormat {
typedef struct Tk_PhotoImageFormatVersion3 {
    const char *\fIname\fR;
    Tk_ImageFileMatchProc *\fIfileMatchProc\fR;
    Tk_ImageStringMatchProc *\fIstringMatchProc\fR;
    Tk_ImageFileReadProc *\fIfileReadProc\fR;
    Tk_ImageStringReadProc *\fIstringReadProc\fR;
    Tk_ImageFileWriteProc *\fIfileWriteProc\fR;
    Tk_ImageStringWriteProc *\fIstringWriteProc\fR;
} \fBTk_PhotoImageFormat\fR;
    Tk_ImageFileMatchProcVersion3 *\fIfileMatchProc\fR;
    Tk_ImageStringMatchProcVersion3 *\fIstringMatchProc\fR;
    Tk_ImageFileReadProcVersion3 *\fIfileReadProc\fR;
    Tk_ImageStringReadProcVersion3 *\fIstringReadProc\fR;
    Tk_ImageFileWriteProcVersion3 *\fIfileWriteProc\fR;
    Tk_ImageStringWriteProcVersion3 *\fIstringWriteProc\fR;
} \fBTk_PhotoImageFormatVersion3\fR;
.CE
.VE 8.7
.PP
The handler need not provide implementations of all six procedures.
For example, the procedures that handle string data would not be
provided for a format in which the image data are stored in binary,
and could therefore contain null characters.  If any procedure is not
implemented, the corresponding pointer in the Tk_PhotoImageFormat
structure should be set to NULL.  The handler must provide the
\fIfileMatchProc\fR procedure if it provides the \fIfileReadProc\fR
procedure, and the \fIstringMatchProc\fR procedure if it provides the
\fIstringReadProc\fR procedure.
.SS NAME
.PP
\fIformatPtr->name\fR provides a name for the image type.
Once \fBTk_CreatePhotoImageFormat\fR returns, this name may be used
in the \fB\-format\fR photo image configuration and subcommand option.
Once \fBTk_CreatePhotoImageFormatVersion3\fR returns, this name may be
used in the \fB\-format\fR photo image configuration and subcommand
option.
The manual page for the photo image (photo(n)) describes how image
file formats are chosen based on their names and the value given to
the \fB\-format\fR option. The first character of \fIformatPtr->name\fR
must not be an uppercase character from the ASCII character set
(that is, one of the characters \fBA\fR-\fBZ\fR).  Such names are used
only for legacy interface support (see below).
.VS 8.7
.SS FILEMATCHPROC
.PP
\fIformatPtr->fileMatchProc\fR provides the address of a procedure for
Tk to call when it is searching for an image file format handler
suitable for reading data in a given file.
\fIformatPtr->fileMatchProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageFileMatchProc\fR(
typedef int \fBTk_ImageFileMatchProcVersion3\fR(
        Tcl_Interp *\fIinterp\fR,
        Tcl_Channel \fIchan\fR,
        const char *\fIfileName\fR,
        Tcl_Obj *\fIformat\fR,
        Tcl_Obj *\fImetadataIn\fR,
        int *\fIwidthPtr\fR,
        int *\fIheightPtr\fR,
        Tcl_Interp *\fIinterp\fR);
        Tcl_Obj *\fImetadataOut\fR);
.CE
The \fIfileName\fR argument is the name of the file containing the
image data, which is open for reading as \fIchan\fR.  The
\fIformat\fR argument contains the value given for the
\fB\-format\fR option, or NULL if the option was not specified.
\fBmetadataIn\fR and \fBmetadataOut\fR inputs and returns a metadata
dictionary as described in section \fBMETADATA INTERFACE\fR below.
If the data in the file appears to be in the format supported by this
handler, the \fIformatPtr->fileMatchProc\fR procedure should store the
width and height of the image in *\fIwidthPtr\fR and *\fIheightPtr\fR
respectively, and return 1.  Otherwise it should return 0.
.SS STRINGMATCHPROC
.PP
\fIformatPtr->stringMatchProc\fR provides the address of a procedure for
Tk to call when it is searching for an image file format handler for
\fIformatPtr->stringMatchProc\fR provides the address of a procedure
for Tk to call when it is searching for an image file format handler
suitable for reading data from a given string.
\fIformatPtr->stringMatchProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageStringMatchProc\fR(
typedef int \fBTk_ImageStringMatchProcVersion3\fR(
        Tcl_Interp *\fIinterp\fR,
        Tcl_Obj *\fIdata\fR,
        Tcl_Obj *\fIformat\fR,
        Tcl_Obj *\fImetadataIn\fR,
        int *\fIwidthPtr\fR,
        int *\fIheightPtr\fR,
        Tcl_Interp *\fIinterp\fR);
        Tcl_Obj *\fImetadataOut\fR);
.CE
The \fIdata\fR argument points to the object containing the image
data.  The \fIformat\fR argument contains the value given for
the \fB\-format\fR option, or NULL if the option was not specified.
\fBmetadataIn\fR and \fBmetadataOut\fR inputs and returns a metadata
dictionary as described in section \fBMETADATA INTERFACE\fR below.
If the data in the string appears to be in the format supported by
this handler, the \fIformatPtr->stringMatchProc\fR procedure should
store the width and height of the image in *\fIwidthPtr\fR and
*\fIheightPtr\fR respectively, and return 1.  Otherwise it should
return 0.
.SS FILEREADPROC
.PP
\fIformatPtr->fileReadProc\fR provides the address of a procedure for
Tk to call to read data from an image file into a photo image.
\fIformatPtr->fileReadProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageFileReadProc\fR(
        Tcl_Interp *\fIinterp\fR,
        Tcl_Channel \fIchan\fR,
        const char *\fIfileName\fR,
        Tcl_Obj *\fIformat\fR,
        Tcl_Obj *\fImetadataIn\fR,
        PhotoHandle \fIimageHandle\fR,
        int \fIdestX\fR, int \fIdestY\fR,
        int \fIwidth\fR, int \fIheight\fR,
        int \fIsrcX\fR, int \fIsrcY\fR);
        int \fIsrcX\fR, int \fIsrcY\fR,
        Tcl_Obj *\fImetadataOut\fR);
.CE
The \fIinterp\fR argument is the interpreter in which the command was
invoked to read the image; it should be used for reporting errors.
The image data is in the file named \fIfileName\fR, which is open for
reading as \fIchan\fR.  The \fIformat\fR argument contains the
value given for the \fB\-format\fR option, or NULL if the option was
not specified.  The image data in the file, or a subimage of it, is to
be read into the photo image identified by the handle
\fIimageHandle\fR.  The subimage of the data in the file is of
dimensions \fIwidth\fR x \fIheight\fR and has its top-left corner at
coordinates (\fIsrcX\fR,\fIsrcY\fR).  It is to be stored in the photo
image with its top-left corner at coordinates
(\fIdestX\fR,\fIdestY\fR) using the \fBTk_PhotoPutBlock\fR procedure.
\fBmetadataIn\fR and \fBmetadataOut\fR inputs and returns a metadata
dictionary as described in section \fBMETADATA INTERFACE\fR below.
The return value is a standard Tcl return value.
.SS STRINGREADPROC
.PP
\fIformatPtr->stringReadProc\fR provides the address of a procedure for
Tk to call to read data from a string into a photo image.
\fIformatPtr->stringReadProc\fR provides the address of a procedure
for Tk to call to read data from a string into a photo image.
\fIformatPtr->stringReadProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageStringReadProc\fR(
        Tcl_Interp *\fIinterp\fR,
        Tcl_Obj *\fIdata\fR,
        Tcl_Obj *\fIformat\fR,
        Tcl_Obj *\fImetadataIn\fR,
        PhotoHandle \fIimageHandle\fR,
        int \fIdestX\fR, int \fIdestY\fR,
        int \fIwidth\fR, int \fIheight\fR,
        int \fIsrcX\fR, int \fIsrcY\fR);
        int \fIsrcX\fR, int \fIsrcY\fR,
        Tcl_Obj *\fImetadataOut\fR);
.CE
The \fIinterp\fR argument is the interpreter in which the command was
invoked to read the image; it should be used for reporting errors.
The \fIdata\fR argument points to the image data in object form.
The \fIformat\fR argument contains the
value given for the \fB\-format\fR option, or NULL if the option was
not specified.  The image data in the string, or a subimage of it, is to
be read into the photo image identified by the handle
not specified.  The image data in the string, or a subimage of it, is
to be read into the photo image identified by the handle
\fIimageHandle\fR.  The subimage of the data in the string is of
dimensions \fIwidth\fR x \fIheight\fR and has its top-left corner at
coordinates (\fIsrcX\fR,\fIsrcY\fR).  It is to be stored in the photo
image with its top-left corner at coordinates
(\fIdestX\fR,\fIdestY\fR) using the \fBTk_PhotoPutBlock\fR procedure.
\fBmetadataIn\fR and \fBmetadataOut\fR inputs and returns a metadata
dictionary as described in section \fBMETADATA INTERFACE\fR below.
The return value is a standard Tcl return value.
.SS FILEWRITEPROC
.PP
\fIformatPtr->fileWriteProc\fR provides the address of a procedure for
Tk to call to write data from a photo image to a file.
\fIformatPtr->fileWriteProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageFileWriteProc\fR(
        Tcl_Interp *\fIinterp\fR,
        const char *\fIfileName\fR,
        Tcl_Obj *\fIformat\fR,
        Tcl_Obj *\fImetadataIn\fR,
        Tk_PhotoImageBlock *\fIblockPtr\fR);
.CE
The \fIinterp\fR argument is the interpreter in which the command was
invoked to write the image; it should be used for reporting errors.
The image data to be written are in memory and are described by the
Tk_PhotoImageBlock structure pointed to by \fIblockPtr\fR; see the
manual page FindPhoto(3) for details.  The \fIfileName\fR argument
points to the string giving the name of the file in which to write the
image data.  The \fIformat\fR argument contains the
value given for the \fB\-format\fR option, or NULL if the option was
not specified.  The format string can contain extra characters
after the name of the format.  If appropriate, the
\fIformatPtr->fileWriteProc\fR procedure may interpret these
characters to specify further details about the image file.
\fBmetadataIn\fR may contain metadata keys that a driver may include
into the output data.
The return value is a standard Tcl return value.
.SS STRINGWRITEPROC
.PP
\fIformatPtr->stringWriteProc\fR provides the address of a procedure for
Tk to call to translate image data from a photo image into a string.
\fIformatPtr->stringWriteProc\fR provides the address of a procedure
for Tk to call to translate image data from a photo image into a
string.
\fIformatPtr->stringWriteProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageStringWriteProc\fR(
        Tcl_Interp *\fIinterp\fR,
        Tcl_Obj *\fIformat\fR,
        Tcl_Obj *\fImetadataIn\fR,
        Tk_PhotoImageBlock *\fIblockPtr\fR);
.CE
The \fIinterp\fR argument is the interpreter in which the command was
invoked to convert the image; it should be used for reporting errors.
The image data to be converted are in memory and are described by the
Tk_PhotoImageBlock structure pointed to by \fIblockPtr\fR; see the
manual page FindPhoto(3) for details.  The data for the string
should be put in the interpreter \fIinterp\fR result.
The \fIformat\fR argument contains the
value given for the \fB\-format\fR option, or NULL if the option was
not specified.  The format string can contain extra characters
after the name of the format.  If appropriate, the
\fIformatPtr->stringWriteProc\fR procedure may interpret these
characters to specify further details about the image file.
\fBmetadataIn\fR may contain metadata keys that a driver may include
into the output data.
The return value is a standard Tcl return value.
.PP
.SH "METADATA INTERFACE"
.PP
Image formats contain a description of the image bitmap and may
contain additional information like image resolution or comments.
Image metadata may be read from image files and passed to the script
level by including dictionary keys into the metadata property of the
image. Image metadata may be written to image data on file write or
image data output.
.PP
.PP
.SS "METADATA KEYS"
.PP
The metadata may contain any key.
A driver will handle only a set of dictionary keys documented in the
documentation. See the photo image manual page for currently defined
keys for the system drivers.
.PP
The following rules may give guidance to name metadata keys:
.RS
Abreviation are in upper case
.RE
.RS
Words are in US English in small case (except proper nouns)
.RE
.RS
Vertical DPI is expressed as DPI/aspect. The reason is, that some
image formats may feature aspect and no resolution value.
.RE
.SS "METADATA INPUT"
.PP
Each driver function gets a Tcl object pointer \fBmetadataIn\fR as
parameter. This parameter serves to input a metadata dict to the
driver function.
It may be NULL to flag that the metadata dict is empty.
.PP
A typical driver code snipped to check for a metadata key is:
.CS
if (NULL != metadataIn) {
    Tcl_Obj *itemData;
    Tcl_DictObjGet(interp, metadataIn, Tcl_NewStringObj("Comment",-1), &itemData));
.CE
.PP
The \-metadata command option data of the following commands is passed
to the driver: \fBimage create\fR, \fBconfigure\fR, \fBput\fR,
\fBread\fR, \fBdata\fR and \fBwrite\fR.
If no \-metadata command option available or not given, the metadata
property of the image is passed to the driver using the following
commands: \fBcget\fR, \fBconfigure\fR, \fBdata\fR and \fBwrite\fR.
.PP
Note that setting the \-metadata property of an image using
\fBconfigure\fR without any other option does not invoke any driver
function.
.PP
The metadata dictionary is not suited to pass options to the driver
related to the bitmap representation, as the image bitmap is not
recreated on a metadata change. The format string should be used for
this purpose.
.PP
.SS "METADATA OUTPUT"
.PP
The image match and read driver functions may set keys in a prepared
matadata dict to return them.
Those functions get a Tcl object pointer \fBmetadataOut\fR as
parameter.
metadataOut may be NULL to indicate, that no metadata return is
attended(\fBput\fR, \fBread\fR subcommands).
\fBmetadataOut\fR is initialized to an empty unshared dict object if
metadata return is attended (\fBimage create\fR command, \fBconfigure\fR
subcommand). The driver may set dict keys in this object to return
metadata.
If a match function succeeds, the metadataOut pointer is passed to the
corresponding read function.
.PP
A sample driver code snippet is:
.CS
if (NULL != metadataOut) {
    Tcl_DictObjPut(NULL, metadataOut, Tcl_NewStringObj("XMP",-1), Tcl_NewStringObj(xmpMetadata);
.CE
.PP
The metadata keys returned by the driver are merged into the present
metadata property of the image or into the metadata dict given by the
\fB\-metadata\fR command line option.
At the script level, the command \fBimage create\fR and the
\fBconfigure\fR method may return metadata from the driver.
.PP
Format string options or metadata keys may influence the creation of
metadata within the driver.
For example, the creation of an expensive metadata key may depend on a
format string option or on a metadata input key.
.PP
.VE 8.7
.SH "VERSION 2 INTERFACE"
.PP
Version 2 Interface does not include the possibility for the driver to
use the metadata dict for input or output.
.SS SYNOPSIS
\fB#include <tk.h>\fR
.sp
\fBTk_CreatePhotoImageFormat\fR(\fIformatPtr\fR)
.SS ARGUMENTS
.AS "const Tk_PhotoImageFormat" *formatPtr
.AP "const Tk_PhotoImageFormat" *formatPtr in
Structure that defines the new file format.
.BE
.SS DESCRIPTION
A driver using the version 2 interface invokes \fBTk_CreatePhotoImageFormat\fR
for driver registration. The Tk_PhotoImageFormat structure
contains the following fields:
.CS
typedef struct Tk_PhotoImageFormat {
    const char *\fIname\fR;
    Tk_ImageFileMatchProc *\fIfileMatchProc\fR;
    Tk_ImageStringMatchProc *\fIstringMatchProc\fR;
    Tk_ImageFileReadProc *\fIfileReadProc\fR;
    Tk_ImageStringReadProc *\fIstringReadProc\fR;
    Tk_ImageFileWriteProc *\fIfileWriteProc\fR;
    Tk_ImageStringWriteProc *\fIstringWriteProc\fR;
} \fBTk_PhotoImageFormat\fR;
.CE
.PP
.SS FILEMATCHPROC
.PP
\fIformatPtr->fileMatchProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageFileMatchProc\fR(
        Tcl_Channel \fIchan\fR,
        const char *\fIfileName\fR,
        Tcl_Obj *\fIformat\fR,
        int *\fIwidthPtr\fR,
        int *\fIheightPtr\fR,
        Tcl_Interp *\fIinterp\fR);
.CE
.PP
.SS STRINGMATCHPROC
.PP
\fIformatPtr->stringMatchProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageStringMatchProc\fR(
        Tcl_Obj *\fIdata\fR,
        Tcl_Obj *\fIformat\fR,
        int *\fIwidthPtr\fR,
        int *\fIheightPtr\fR,
        Tcl_Interp *\fIinterp\fR);
.CE
.SS FILEREADPROC
.PP
\fIformatPtr->fileReadProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageFileReadProc\fR(
        Tcl_Interp *\fIinterp\fR,
        Tcl_Channel \fIchan\fR,
        const char *\fIfileName\fR,
        Tcl_Obj *\fIformat\fR,
        PhotoHandle \fIimageHandle\fR,
        int \fIdestX\fR, int \fIdestY\fR,
        int \fIwidth\fR, int \fIheight\fR,
        int \fIsrcX\fR, int \fIsrcY\fR);
.CE
.SS STRINGREADPROC
.PP
\fIformatPtr->stringReadProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageStringReadProc\fR(
        Tcl_Interp *\fIinterp\fR,
        Tcl_Obj *\fIdata\fR,
        Tcl_Obj *\fIformat\fR,
        PhotoHandle \fIimageHandle\fR,
        int \fIdestX\fR, int \fIdestY\fR,
        int \fIwidth\fR, int \fIheight\fR,
        int \fIsrcX\fR, int \fIsrcY\fR);
.CE
.SS FILEWRITEPROC
.PP
\fIformatPtr->fileWriteProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageFileWriteProc\fR(
        Tcl_Interp *\fIinterp\fR,
        const char *\fIfileName\fR,
        Tcl_Obj *\fIformat\fR,
        Tk_PhotoImageBlock *\fIblockPtr\fR);
.CE
.SS STRINGWRITEPROC
.PP
\fIformatPtr->stringWriteProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageStringWriteProc\fR(
        Tcl_Interp *\fIinterp\fR,
        Tcl_Obj *\fIformat\fR,
        Tk_PhotoImageBlock *\fIblockPtr\fR);
.CE
.PP
.SH "LEGACY INTERFACE SUPPORT"
.PP
In Tk 8.2 and earlier, the definition of all the function pointer
types stored in fields of a \fBTk_PhotoImageFormat\fR struct were
incompatibly different.  Legacy programs and libraries dating from
those days may still contain code that defines extended Tk photo image
formats using the old interface.  The Tk header file will still support

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
1
2
3
4
5
6
7
8
9
10
11

12
13
14
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 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_CreateEventHandler 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateEventHandler, Tk_DeleteEventHandler \- associate procedure callback with an X event
Tk_CreateEventHandler, Tk_DeleteEventHandler, Tk_GetButtonMask, Tk_SendVirtualEvent \- associate procedure callback with an X event
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateEventHandler\fR(\fItkwin, mask, proc, clientData\fR)
.sp
\fBTk_DeleteEventHandler\fR(\fItkwin, mask, proc, clientData\fR)
.sp
\fBTk_GetButtonMask\fR(\fIbutton\fR)
.sp
\fBTk_SendVirtualEvent\fR(\fItkwin, eventName, detail\fR)
.SH ARGUMENTS
.AS "unsigned long" clientData
.AP unsigned button in
Button number.
.AP "const char" *eventName in
The name of the virtual event.
.AP Tcl_Obj *detail in
Detail information for the virtual event.
.AP Tk_Window tkwin in
Token for window in which events may occur.
.AP "unsigned long" mask in
Bit-mask of events (such as \fBButtonPressMask\fR)
for which \fIproc\fR should be called.
.AP Tk_EventProc *proc in
Procedure to invoke whenever an event in \fImask\fR occurs
67
68
69
70
71
72
73





74
75
77
78
79
80
81
82
83
84
85
86
87
88
89
90







+
+
+
+
+


When a window is deleted all of its handlers will be deleted
automatically;  in this case there is no need to call
\fBTk_DeleteEventHandler\fR.
.PP
If multiple handlers are declared for the same type of X event
on the same window, then the handlers will be invoked in the
order they were created.
.PP
\fBTk_GetButtonMask\fR returns the button mask corresponding to
the button. E.g it will return \fIButton1Mask\fR for button \fIButton1\fR.
.PP
\fBTk_SendVirtualEvent\fR sends a virtual event to Tk's event queue.
.SH KEYWORDS
bind, callback, event, handler

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
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35











-
+













+
+
+







'\"
'\" Copyright (c) 1990-1992 The Regents of the University of California.
'\" Copyright (c) 1994-1998 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_AllocFontFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_AllocFontFromObj, Tk_GetFont, Tk_GetFontFromObj, Tk_NameOfFont, Tk_FreeFontFromObj, Tk_FreeFont \- maintain database of fonts
Tk_AllocFontFromObj, Tk_GetFont, Tk_GetFontFromObj, Tk_NameOfFont, Tk_FontGetDescription, Tk_FreeFontFromObj, Tk_FreeFont \- maintain database of fonts
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Font
\fBTk_AllocFontFromObj(\fIinterp, tkwin, objPtr\fB)\fR
.sp
Tk_Font
\fBTk_GetFont(\fIinterp, tkwin, string\fB)\fR
.sp
Tk_Font
\fBTk_GetFontFromObj(\fItkwin, objPtr\fB)\fR
.sp
Tcl_Obj *
\fBTk_FontGetDescription(\fItkfont\fB)\fR
.sp
const char *
\fBTk_NameOfFont(\fItkfont\fB)\fR
.sp
Tk_Font
\fBTk_FreeFontFromObj(\fItkwin, objPtr\fB)\fR
.sp
void
84
85
86
87
88
89
90



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







+
+
+







\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/GetHINSTANCE.3.

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 Tk_GetHISTANCE 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetHINSTANCE \- retrieve the global application instance handle

Changes to doc/GetHWND.3.

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 HWND 3 8.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetHWND, Tk_AttachHWND \- manage interactions between the Windows handle and an X window

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
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29











-
+







+
+
+







'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-1998 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_GetPixelsFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetPixelsFromObj, Tk_GetPixels, Tk_GetMMFromObj, Tk_GetScreenMM \- translate between strings and screen units
Tk_GetPixelsFromObj, Tk_GetPixels, Tk_GetMMFromObj, Tk_GetScreenMM, Tk_GetDoublePixelsFromObj \- translate between strings and screen units
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetPixelsFromObj(\fIinterp, tkwin, objPtr, intPtr\fB)\fR
.sp
int
\fBTk_GetDoublePixelsFromObj(\fIinterp, tkwin, objPtr, doublePtr\fB)\fR
.sp
int
\fBTk_GetPixels(\fIinterp, tkwin, string, intPtr\fB)\fR
.sp
int
\fBTk_GetMMFromObj(\fIinterp, tkwin, objPtr, doublePtr\fB)\fR
.sp
int
76
77
78
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
96
97
98
99
100
101







+
+
+













If an error occurs (e.g. \fIobjPtr\fR contains a number followed
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/GetScroll.3.

21
22
23
24
25
26
27
28

29
30
31
32
33
34

35
36
37
38
39
40
41
21
22
23
24
25
26
27

28
29
30
31
32
33

34
35
36
37
38
39
40
41







-
+





-
+







\fBTk_GetScrollInfo(\fIinterp, argc, argv, fractionPtr, stepsPtr\fB)\fR
.SH ARGUMENTS
.AS "Tcl_Interp" *fractionPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP int objc in
Number of Tcl_Obj's in \fIobjv\fR array.
.AP "Tcl_Obj *const" objv[] in
.AP "Tcl_Obj *const *" objv in
Argument objects.  These represent the entire widget command, of
which the first word is typically the widget name and the second
word is typically \fBxview\fR or \fByview\fR.
.AP int argc in
Number of strings in \fIargv\fR array.
.AP "const char" *argv[] in
.AP "const char **" argv in
Argument strings.  These represent the entire widget command, of
which the first word is typically the widget name and the second
word is typically \fBxview\fR or \fByview\fR.
.AP double *fractionPtr out
Filled in with fraction from \fBmoveto\fR option, if any.
.AP int *stepsPtr out
Filled in with line or page count from \fBscroll\fR option, if any.
58
59
60
61
62
63
64
65


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

65
66
67
68
69
70
71
72
73
74
75
76







-
+
+










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 proper integer.
in with the \fInumber\fR value, which must be a  integer or a float,
but if it is a float then it is converted to an integer, rounded away from 0.
If an error occurs in parsing the arguments, \fBTK_SCROLL_ERROR\fR
is returned and an error message is left in interpreter
\fIinterp\fR's result.
.PP
\fBTk_GetScrollInfo\fR is identical in function to
\fBTk_GetScrollInfoObj\fR.  However, \fBTk_GetScrollInfo\fR accepts
string arguments, making it more appropriate for use with legacy
widgets.
.SH KEYWORDS
parse, scrollbar, scrolling command, xview, yview

Changes to doc/Grab.3.

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 Tk_Grab 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_Grab, Tk_Ungrab \- manipulate grab state in an application

Changes to doc/HWNDToWindow.3.

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 Tk_HWNDToWindow 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_HWNDToWindow \- Find Tk's window information for a Windows window

Changes to doc/ImgChanged.3.

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
24
25
26
27







-
+

-
-
+
+







.BS
.SH NAME
Tk_ImageChanged \- notify widgets that image needs to be redrawn
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_ImageChanged\fR(\fIimageMaster, x, y, width, height, imageWidth, imageHeight\fR)
\fBTk_ImageChanged\fR(\fImodel, x, y, width, height, imageWidth, imageHeight\fR)
.SH ARGUMENTS
.AS Tk_ImageMaster imageHeight
.AP Tk_ImageMaster imageMaster in
.AS Tk_ImageModel imageHeight
.AP Tk_ImageModel model in
Token for image, which was passed to image's \fIcreateProc\fR when
the image was created.
.AP int x in
X-coordinate of upper-left corner of region that needs redisplay (measured
from upper-left corner of image).
.AP int y in
Y-coordinate of upper-left corner of region that needs redisplay (measured
38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52







-
+







.SH DESCRIPTION
.PP
An image manager calls \fBTk_ImageChanged\fR for an image
whenever anything happens that requires the image to be redrawn.
As a result of calling \fBTk_ImageChanged\fR, any widgets using
the image are notified so that they can redisplay themselves
appropriately.
The \fIimageMaster\fR argument identifies the image, and
The \fImodel\fR argument identifies the image, and
\fIx\fR, \fIy\fR, \fIwidth\fR, and \fIheight\fR
specify a rectangular region within the image that needs to
be redrawn.
\fIimageWidth\fR and \fIimageHeight\fR specify the image's (new) size.
.PP
An image manager should call \fBTk_ImageChanged\fR during
its \fIcreateProc\fR to specify the image's initial size and to

Changes to doc/Inactive.3.

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 Tk_GetUserInactiveTime 3 8.5 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetUserInactiveTime, Tk_ResetUserInactiveTime \- discover user inactivity time

Changes to doc/MaintGeom.3.

10
11
12
13
14
15
16
17

18
19

20
21
22


23
24
25


26
27
28
29



30
31
32
33



34
35

36
37

38
39
40
41
42

43
44

45
46
47
48



49
50
51


52
53

54
55
56


57
58
59
60



61
62
63
64
65



66
67
68


69
70
71


72
73
74


75
76
77


78
79
80
81
82
83
84
85
86

87
88
89
90

91
92
93
94

95
96

97
98
99

10
11
12
13
14
15
16

17
18

19
20


21
22
23


24
25
26



27
28
29
30



31
32
33
34

35
36

37
38
39
40
41

42
43

44
45



46
47
48
49


50
51
52

53
54


55
56
57



58
59
60
61
62



63
64
65
66


67
68
69


70
71
72


73
74
75


76
77
78
79
80
81
82
83
84
85

86
87
88
89

90
91
92
93

94
95

96
97
98

99







-
+

-
+

-
-
+
+

-
-
+
+

-
-
-
+
+
+

-
-
-
+
+
+

-
+

-
+




-
+

-
+

-
-
-
+
+
+

-
-
+
+

-
+

-
-
+
+

-
-
-
+
+
+


-
-
-
+
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+








-
+



-
+



-
+

-
+


-
+
.BS
.SH NAME
Tk_MaintainGeometry, Tk_UnmaintainGeometry \- maintain geometry of one window relative to another
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_MaintainGeometry\fR(\fIslave, master, x, y, width, height\fR)
\fBTk_MaintainGeometry\fR(\fIwindow, container, x, y, width, height\fR)
.sp
\fBTk_UnmaintainGeometry\fR(\fIslave, master\fR)
\fBTk_UnmaintainGeometry\fR(\fIwindow, container\fR)
.SH ARGUMENTS
.AS Tk_Window master
.AP Tk_Window slave in
.AS Tk_Window container
.AP Tk_Window window in
Window whose geometry is to be controlled.
.AP Tk_Window master in
Window relative to which \fIslave\fR's geometry will be controlled.
.AP Tk_Window container in
Window relative to which \fIwindow\fR's geometry will be controlled.
.AP int x in
Desired x-coordinate of \fIslave\fR in \fImaster\fR, measured in pixels
from the inside of \fImaster\fR's left border to the outside of
\fIslave\fR's left border.
Desired x-coordinate of \fIwindow\fR in \fIcontainer\fR, measured in pixels
from the inside of \fIcontainer\fR's left border to the outside of
\fIwindow\fR's left border.
.AP int y in
Desired y-coordinate of \fIslave\fR in \fImaster\fR, measured in pixels
from the inside of \fImaster\fR's top border to the outside of
\fIslave\fR's top border.
Desired y-coordinate of \fIwindow\fR in \fIcontainer\fR, measured in pixels
from the inside of \fIcontainer\fR's top border to the outside of
\fIwindow\fR's top border.
.AP int width in
Desired width for \fIslave\fR, in pixels.
Desired width for \fIwindow\fR, in pixels.
.AP int height in
Desired height for \fIslave\fR, in pixels.
Desired height for \fIwindow\fR, in pixels.
.BE
.SH DESCRIPTION
.PP
\fBTk_MaintainGeometry\fR and \fBTk_UnmaintainGeometry\fR make it
easier for geometry managers to deal with slaves whose masters are not
easier for geometry managers to deal with windows whose containers are not
their parents.
Three problems arise if the master for a slave is not its parent:
Three problems arise if the container for a window is not its parent:
.IP [1]
The x- and y-position of the slave must be translated from the
coordinate system of the master to that of the parent before
positioning the slave.
The x- and y-position of the window must be translated from the
coordinate system of the container to that of the parent before
positioning the window.
.IP [2]
If the master window, or any of its ancestors up to the slave's
parent, is moved, then the slave must be repositioned within its
If the container window, or any of its ancestors up to the window's
parent, is moved, then the window must be repositioned within its
parent in order to maintain the correct position relative to the
master.
container.
.IP [3]
If the master or one of its ancestors is mapped or unmapped, then
the slave must be mapped or unmapped to correspond.
If the container or one of its ancestors is mapped or unmapped, then
the window must be mapped or unmapped to correspond.
.LP
None of these problems is an issue if the parent and master are
the same.  For example, if the master or one of its ancestors
is unmapped, the slave is automatically removed by the screen
None of these problems is an issue if the parent and container are
the same.  For example, if the container or one of its ancestors
is unmapped, the window is automatically removed by the screen
by X.
.PP
\fBTk_MaintainGeometry\fR deals with these problems for slaves
whose masters are not their parents, as well as handling the simpler
case of slaves whose masters are their parents.
\fBTk_MaintainGeometry\fR deals with these problems for windows
whose containers are not their parents, as well as handling the simpler
case of windows whose container are their parents.
\fBTk_MaintainGeometry\fR is typically called by a window manager
once it has decided where a slave should be positioned relative
to its master.
once it has decided where a window should be positioned relative
to its container.
\fBTk_MaintainGeometry\fR translates the coordinates to the
coordinate system of \fIslave\fR's parent and then moves and
resizes the slave appropriately.
coordinate system of \fIwindow\fR's parent and then moves and
resizes the window appropriately.
Furthermore, it remembers the desired position and creates event
handlers to monitor the master and all of its ancestors up
to (but not including) the slave's parent.
handlers to monitor the container and all of its ancestors up
to (but not including) the window's parent.
If any of these windows is moved, mapped, or unmapped,
the slave will be adjusted so that it is mapped only when the
master is mapped and its geometry relative to the master
the window will be adjusted so that it is mapped only when the
container is mapped and its geometry relative to the container
remains as specified by \fIx\fR, \fIy\fR, \fIwidth\fR, and
\fIheight\fR.
.PP
When a window manager relinquishes control over a window, or
if it decides that it does not want the window to appear on the
screen under any conditions, it calls \fBTk_UnmaintainGeometry\fR.
\fBTk_UnmaintainGeometry\fR unmaps the window and cancels any
previous calls to \fBTk_MaintainGeometry\fR for the
\fImaster\fR\-\fIslave\fR pair, so that the slave's
\fIcontainer\fR\-\fIwindow\fR pair, so that the window's
geometry and mapped state are no longer maintained
automatically.
\fBTk_UnmaintainGeometry\fR need not be called by a geometry
manager if the slave, the master, or any of the master's ancestors
manager if the window, the container, or any of the container's ancestors
is destroyed:  Tk will call it automatically.
.PP
If \fBTk_MaintainGeometry\fR is called repeatedly for the same
\fImaster\fR\-\fIslave\fR pair, the information from the most
\fIcontainer\fR\-\fIwindow\fR pair, the information from the most
recent call supersedes any older information.
If \fBTk_UnmaintainGeometry\fR is called for a \fImaster\fR\-\fIslave\fR
If \fBTk_UnmaintainGeometry\fR is called for a \fIcontainer\fR\-\fIwindow\fR
pair that is is not currently managed, the call has no effect.
.SH KEYWORDS
geometry manager, map, master, parent, position, slave, unmap
geometry manager, map, container, parent, position, window, unmap

Changes to doc/ManageGeom.3.

28
29
30
31
32
33
34
35

36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56

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

71
72

73
74
75

76
77
78
79
80

81
82
83

84
85
86
87

88
89
90
28
29
30
31
32
33
34

35
36
37
38
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55

56
57
58
59
60
61
62
63
64
65
66
67
68
69

70
71

72
73
74

75
76
77
78
79

80
81
82

83
84
85
86

87
88
89
90







-
+











-
+








-
+













-
+

-
+


-
+




-
+


-
+



-
+



.AP ClientData clientData in
Arbitrary one-word value to pass to geometry manager callbacks.
.BE
.SH DESCRIPTION
.PP
\fBTk_ManageGeometry\fR arranges for a particular geometry manager,
described by the \fImgrPtr\fR argument, to control the geometry
of a particular slave window, given by \fItkwin\fR.
of a particular content window, given by \fItkwin\fR.
If \fItkwin\fR was previously managed by some other geometry manager,
the previous manager loses control in favor of the new one.
If \fImgrPtr\fR is NULL, geometry management is cancelled for
\fItkwin\fR.
.PP
The structure pointed to by \fImgrPtr\fR contains information about
the geometry manager:
.CS
typedef struct {
    const char *\fIname\fR;
    Tk_GeomRequestProc *\fIrequestProc\fR;
    Tk_GeomLostSlaveProc *\fIlostSlaveProc\fR;
    Tk_GeomLostContentProc *\fIlostContentProc\fR;
} \fBTk_GeomMgr\fR;
.CE
The \fIname\fR field is the textual name for the geometry manager,
such as \fBpack\fR or \fBplace\fR;  this value will be returned
by the command \fBwinfo manager\fR.
.PP
\fIrequestProc\fR is a procedure in the geometry manager that
will be invoked whenever \fBTk_GeometryRequest\fR is called by the
slave to change its desired geometry.
content window to change its desired geometry.
\fIrequestProc\fR should have arguments and results that match the
type \fBTk_GeomRequestProc\fR:
.CS
typedef void \fBTk_GeomRequestProc\fR(
        ClientData \fIclientData\fR,
        Tk_Window \fItkwin\fR);
.CE
The parameters to \fIrequestProc\fR will be identical to the
corresponding parameters passed to \fBTk_ManageGeometry\fR.
\fIclientData\fR usually points to a data
structure containing application-specific information about
how to manage \fItkwin\fR's geometry.
.PP
The \fIlostSlaveProc\fR field of \fImgrPtr\fR points to another
The \fIlostContentProc\fR field of \fImgrPtr\fR points to another
procedure in the geometry manager.
Tk will invoke \fIlostSlaveProc\fR if some other manager
Tk will invoke \fIlostContentProc\fR if some other manager
calls \fBTk_ManageGeometry\fR to claim
\fItkwin\fR away from the current geometry manager.
\fIlostSlaveProc\fR is not invoked if \fBTk_ManageGeometry\fR is
\fIlostContentProc\fR is not invoked if \fBTk_ManageGeometry\fR is
called with a NULL value for \fImgrPtr\fR (presumably the current
geometry manager has made this call, so it already knows that the
window is no longer managed), nor is it called if \fImgrPtr\fR
is the same as the window's current geometry manager.
\fIlostSlaveProc\fR should have
\fIlostContentProc\fR should have
arguments and results that match the following prototype:
.CS
typedef void \fBTk_GeomLostSlaveProc\fR(
typedef void \fBTk_GeomLostContentProc\fR(
        ClientData \fIclientData\fR,
        Tk_Window \fItkwin\fR);
.CE
The parameters to \fIlostSlaveProc\fR will be identical to the
The parameters to \fIlostContentProc\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
10
11
12
13
14
15
16

17
18


19
20
21
22
23
24
25
26
27







-
+

-
-
+
+







.SH NAME
Tk_NameOfImage \- Return name of image.
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
const char *
\fBTk_NameOfImage\fR(\fIimageMaster\fR)
\fBTk_NameOfImage\fR(\fIimageModel\fR)
.SH ARGUMENTS
.AS Tk_ImageMaster imageMaster
.AP Tk_ImageMaster imageMaster in
.AS Tk_ImageModel imageModel
.AP Tk_ImageModel imageModel in
Token for image, which was passed to image manager's \fIcreateProc\fR when
the image was created.
.BE
.SH DESCRIPTION
.PP
This procedure is invoked by image managers to find out the name
of an image.  Given the token for the image, it returns the

Changes to doc/SetOptions.3.

56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
56
57
58
59
60
61
62

63
64
65
66
67
68
69
70







-
+







.AP Tk_Window tkwin in
For options such as \fBTK_OPTION_COLOR\fR, this argument indicates
the window in which the option will be used.  If \fIoptionTable\fR uses
no window-dependent options, then a NULL value may be supplied for
this argument.
.AP int objc in
Number of values in \fIobjv\fR.
.AP Tcl_Obj "*const objv[]" in
.AP Tcl_Obj "*const *objv" in
Command-line arguments for setting configuring options.
.AP Tk_SavedOptions *savePtr out
If not NULL, the structure pointed to by this argument is filled
in with the old values of any options that were modified and old
values are restored automatically if an error occurs in \fBTk_SetOptions\fR.
.AP int *maskPtr out
If not NULL, the word pointed to by \fImaskPtr\fR is filled in with the

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
1
2
3
4
5
6
7
8
9
10
11

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











-
+



















+
+
+







'\"
'\" Copyright (c) 1990-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_WindowId 3 "8.4" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_WindowId, Tk_Parent, Tk_Display, Tk_DisplayName, Tk_ScreenNumber, Tk_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
Tk_WindowId, Tk_Parent, Tk_Display, Tk_DisplayName, Tk_ScreenNumber, Tk_AlwaysShowSelection, Tk_Screen, Tk_X, Tk_Y, Tk_Width, Tk_Height, Tk_Changes, Tk_Attributes, Tk_IsContainer, Tk_IsEmbedded, Tk_IsMapped, Tk_IsTopLevel, Tk_ReqWidth, Tk_ReqHeight, Tk_MinReqWidth, Tk_MinReqHeight, Tk_InternalBorderLeft, Tk_InternalBorderRight, Tk_InternalBorderTop, Tk_InternalBorderBottom, Tk_Visual, Tk_Depth, Tk_Colormap, Tk_Interp, Tk_NewWindowObj  \- retrieve information from Tk's local data structure
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Window
\fBTk_WindowId\fR(\fItkwin\fR)
.sp
Tk_Window
\fBTk_Parent\fR(\fItkwin\fR)
.sp
Display *
\fBTk_Display\fR(\fItkwin\fR)
.sp
const char *
\fBTk_DisplayName\fR(\fItkwin\fR)
.sp
int
\fBTk_ScreenNumber\fR(\fItkwin\fR)
.sp
int
\fBTk_AlwaysShowSelection\fR(\fItkwin\fR)
.sp
Screen *
\fBTk_Screen\fR(\fItkwin\fR)
.sp
int
\fBTk_X\fR(\fItkwin\fR)
.sp
int
93
94
95
96
97
98
99



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







+
+
+







\fBTk_Depth\fR(\fItkwin\fR)
.sp
Colormap
\fBTk_Colormap\fR(\fItkwin\fR)
.sp
Tcl_Interp *
\fBTk_Interp\fR(\fItkwin\fR)
.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
123
124
125
126
127
128
129


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







+
+







.PP
\fBTk_Display\fR returns a pointer to the Xlib display structure
corresponding to \fItkwin\fR.  \fBTk_DisplayName\fR returns an
ASCII string identifying \fItkwin\fR's display.  \fBTk_ScreenNumber\fR
returns the index of \fItkwin\fR's screen among all the screens
of \fItkwin\fR's display.  \fBTk_Screen\fR returns a pointer to
the Xlib structure corresponding to \fItkwin\fR's screen.
\fBTk_AlwaysShowSelection\fR indicates whether text/entry widgets
should always display their selection, regardless of window focus.
.PP
\fBTk_X\fR, \fBTk_Y\fR, \fBTk_Width\fR, and \fBTk_Height\fR
return information about \fItkwin's\fR location within its
parent and its size.  The location information refers to the
upper-left pixel in the window, or its border if there is one.
The width and height information refers to the interior size
of the window, not including any border.  \fBTk_Changes\fR
178
179
180
181
182
183
184


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







+
+




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.

1
2
3
4

5
6
7
8
9
10
11
1
2
3

4
5
6
7
8
9
10
11



-
+







'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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.
'\"
.TH bind n 8.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
197
198
199
200
201
202
203
204
205


206
207

208
209

210
211












212
213
214
215
216
217
218
197
198
199
200
201
202
203


204
205
206

207
208

209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230







-
-
+
+

-
+

-
+


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







active.  Likewise, the \fBDeactive\fR event is sent when the window's
state changes from active to deactive.  There are no useful percent
substitutions you would make when binding to these events.
.IP \fBMouseWheel\fR 5
Many contemporary mice support a mouse wheel, which is used
for scrolling documents without using the scrollbars.  By rolling the
wheel, the system will generate \fBMouseWheel\fR events that the
application can use to scroll.  Like \fBKey\fR events the event is
always routed to the window that currently has focus. When the event
application can use to scroll.  The event is routed to the
window currently under the mouse pointer. When the event
is received you can use the \fB%D\fR substitution to get the
\fIdelta\fR field for the event, which is a integer value describing how
\fIdelta\fR field for the event, which is an integer value describing how
the mouse wheel has moved.  The smallest value for which the
system will report is defined by the OS. The sign of the
system will report is defined by the OS.  The sign of the
value determines which direction your widget should scroll.  Positive
values should scroll up and negative values should scroll down.
.RS
.PP
Horizontal scrolling uses \fBShift-MouseWheel\fR events, with positive
\fB%D\fR \fIdelta\fR substitution indicating left scrolling and negative
right scrolling.
Horizontal scrolling events may fire from
many different hardware units such as tilt wheels or touchpads.  Horizontal
scrolling can also be emulated by holding Shift and scrolling vertically.
.RE
.IP "\fBKeyPress\fR, \fBKeyRelease\fR" 5
The \fBKeyPress\fR and \fBKeyRelease\fR events are generated
whenever a key is pressed or released.  \fBKeyPress\fR and \fBKeyRelease\fR
.IP "\fBKey\fR, \fBKeyRelease\fR" 5
The \fBKey\fR and \fBKeyRelease\fR events are generated
whenever a key is pressed or released.  \fBKey\fR and \fBKeyRelease\fR
events are sent to the window which currently has the keyboard focus.
.IP "\fBButton\fR, \fBButtonRelease\fR, \fBMotion\fR" 5
The \fBButton\fR and \fBButtonRelease\fR events
are generated when the user presses or releases a mouse button.
266
267
268
269
270
271
272
273


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

285
286
287
288
289
290
291
292
293







-
+
+







A \fBDestroy\fR event is delivered to a window when
it is destroyed.
.RS
.PP
When the \fBDestroy\fR event is delivered
to a widget, it is in a
.QW half-dead
state: the widget still exists, but most operations on it will fail.
state: the widget still exists, but operations that involve it
may return invalid results, or return an error.
.RE
.IP "\fBFocusIn\fR, \fBFocusOut\fR" 5
The \fBFocusIn\fR and \fBFocusOut\fR events are generated
whenever the keyboard focus changes.
A \fBFocusOut\fR event is sent to the old focus window,
and a \fBFocusIn\fR event is sent to the new one.
.RS

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 arg ...\fR?
\fIimageName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for bitmap images:
.TP
\fIimageName \fBcget\fR \fIoption\fR
.

Changes to doc/button.n.

105
106
107
108
109
110
111
112

113
114
115
116
117
118
119
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119







-
+







.SH "WIDGET COMMAND"
.PP
The \fBbutton\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for button widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
Returns the current value of the configuration option given

Changes to doc/canvas.n.

344
345
346
347
348
349
350
351

352
353
354
355
356
357

358
359
360
361
362
363
364
344
345
346
347
348
349
350

351
352
353
354
355
356

357
358
359
360
361
362
363
364







-
+





-
+







.SH "WIDGET COMMAND"
.PP
The \fBcanvas\fR command creates a new Tcl command whose
name is \fIpathName\fR. This
command may be used to invoke various
operations on the widget. It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
The following widget commands are possible for canvas widgets:
.TP
\fIpathName \fBaddtag \fItag searchSpec \fR?\fIarg arg ...\fR?
\fIpathName \fBaddtag \fItag searchSpec \fR?\fIarg ...\fR?
.
For each item that meets the constraints specified by
\fIsearchSpec\fR and the \fIarg\fRs, add
\fItag\fR to the list of tags associated with the item if it
is not already present on that list.
It is possible that no items will satisfy the constraints
given by \fIsearchSpec\fR and \fIarg\fRs, in which case the
598
599
600
601
602
603
604
605

606
607
608
609
610
611
612
598
599
600
601
602
603
604

605
606
607
608
609
610
611
612







-
+







tag given by \fItagToDelete\fR from the list of those
associated with the item.
If an item does not have the tag \fItagToDelete\fR then
the item is unaffected by the command.
If \fItagToDelete\fR is omitted then it defaults to \fItagOrId\fR.
This command returns an empty string.
.TP
\fIpathName \fBfind \fIsearchCommand \fR?\fIarg arg ...\fR?
\fIpathName \fBfind \fIsearchCommand \fR?\fIarg ...\fR?
.
This command returns a list consisting of all the items that
meet the constraints specified by \fIsearchCommand\fR and
\fIarg\fR's.
\fISearchCommand\fR and \fIargs\fR have any of the forms
accepted by the \fBaddtag\fR command.
The items are returned in stacking order, with the lowest item first.
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
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







-
+
+












-
+







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.
\fINumber\fR must be an integer or a float, but if it is a float then
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR or an abbreviation
of one of these.
If \fIwhat is \fBpages\fR then the view
adjusts in units of nine-tenths the window's width.
If \fInumber\fR is negative then information farther to the left
becomes visible; if it is positive then information farther to the right
becomes visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right in units
of the \fBxScrollIncrement\fR option, if it is greater than zero,
or in units of one-tenth the window's width otherwise.
.RE
.TP
\fIpathName \fByview \fI?args\fR?
\fIpathName \fByview ?\fIargs\fR?
.
This command is used to query and change the vertical position of the
information displayed in the canvas's window.
It can take any of the following forms:
.RS
.TP
\fIpathName \fByview\fR

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 arg ...\fR?
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for checkbutton widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
Returns the current value of the configuration option given

Changes to doc/chooseDirectory.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 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

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 arg ...\fR?
\fBclipboard \fIoption\fR ?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
This command provides a Tcl interface to the Tk clipboard,
which stores data for later retrieval using the selection mechanism
(via the \fB\-selection CLIPBOARD\fR option).
In order to copy data into the clipboard, \fBclipboard clear\fR must

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 <[email protected]>
'\" Copyright (c) 2008 Donal K. Fellows
'\"
.TH colors n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
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
780
781
782
783
784
785
786




787
788
789
790
791
792
793
794

795
796

797
798
799
800





801
802
803

804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822

823

824
825

826


827
828
829
830
831
832
833

834
835


836
837
838
839
840
841


842
843

844
845







846
847

848



849




850
851
852







853






854
855

856
857
858
859
860
861







862
863
864
865


866

867



868
869
870


871
872
873
874






875
876
877
878
879


880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914

915
916
917
918
919
920
921









922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944







-
-
-
-
+
+
+
+
+



-


-




-
-
-
-
-



-



















-

-


-

-
-







-


-
-






-
-


-


-
-
-
-
-
-
-


-

-
-
-

-
-
-
-



-
-
-
-
-
-
-

-
-
-
-
-
-


-






-
-
-
-
-
-
-




-
-

-

-
-
-



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







+


+


+
+
+
+
+
+
+
+
+












-







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




+









yellow4	139	139 	0
YellowGreen	154	205 	50
.DE
.SH "PORTABILITY ISSUES"
.TP
\fBMac OS X\fR
.
On macOS, the following additional system colors are available.
This first group contains all colors available in the HIToolbox library.
(Note that in some cases the actual color values may depend on the
current Appearance.)
On macOS, the following additional system colors are available.  This
first group contains all of the HIBrush colors available in the
HIToolbox library. Note that on macOS 10.14 (Mojave) and later these
colors are unlikely to match the color actually used for the purpose
suggested by the color name.
.RS
.DS
systemActiveAreaFill
systemAlertActiveText
systemAlertBackgroundActive
systemAlertBackgroundInactive
systemAlertInactiveText
systemAlternatePrimaryHighlightColor
systemAppleGuideCoachmark
systemBevelActiveDark
systemBevelActiveLight
systemBevelButtonActiveText
systemBevelButtonInactiveText
systemBevelButtonPressedText
systemBevelButtonStickyActiveText
systemBevelButtonStickyInactiveText
systemBevelInactiveDark
systemBevelInactiveLight
systemBlack
systemBlackText
systemButtonActiveDarkHighlight
systemButtonActiveDarkShadow
systemButtonActiveLightHighlight
systemButtonActiveLightShadow
systemButtonFace
systemButtonFaceActive
systemButtonFaceInactive
systemButtonFacePressed
systemButtonFrame
systemButtonFrameActive
systemButtonFrameInactive
systemButtonInactiveDarkHighlight
systemButtonInactiveDarkShadow
systemButtonInactiveLightHighlight
systemButtonInactiveLightShadow
systemButtonPressedDarkHighlight
systemButtonPressedDarkShadow
systemButtonPressedLightHighlight
systemButtonPressedLightShadow
systemButtonText
systemChasingArrows
systemDialogActiveText
systemDialogBackgroundActive
systemDialogBackgroundInactive
systemDialogInactiveText
systemDocumentWindowBackground
systemDocumentWindowTitleActiveText
systemDocumentWindowTitleInactiveText
systemDragHilite
systemDrawerBackground
systemFinderWindowBackground
systemFocusHighlight
systemHighlight
systemHighlightAlternate
systemHighlightSecondary
systemHighlightText
systemIconLabelBackground
systemIconLabelBackgroundSelected
systemIconLabelSelectedText
systemIconLabelText
systemListViewBackground
systemListViewColumnDivider
systemListViewEvenRowBackground
systemListViewOddRowBackground
systemListViewSeparator
systemListViewSortColumnBackground
systemListViewText
systemListViewWindowHeaderBackground
systemMenu
systemMenuActive
systemMenuActiveText
systemMenuBackground
systemMenuBackgroundSelected
systemMenuDisabled
systemMenuItemActiveText
systemMenuItemDisabledText
systemMenuItemSelectedText
systemMenuText
systemMetalBackground
systemModelessDialogActiveText
systemModelessDialogBackgroundActive
systemModelessDialogBackgroundInactive
systemModelessDialogInactiveText
systemMovableModalBackground
systemMovableModalWindowTitleActiveText
systemMovableModalWindowTitleInactiveText
systemNotificationText
systemNotificationWindowBackground
systemPlacardActiveText
systemPlacardBackground
systemPlacardInactiveText
systemPlacardPressedText
systemPopupArrowActive
systemPopupArrowInactive
systemPopupArrowPressed
systemPopupButtonActiveText
systemPopupButtonInactiveText
systemPopupButtonPressedText
systemPopupLabelActiveText
systemPopupLabelInactiveText
systemPopupWindowTitleActiveText
systemPopupWindowTitleInactiveText
systemPrimaryHighlightColor
systemPushButtonActiveText
systemPushButtonInactiveText
systemPushButtonPressedText
systemRootMenuActiveText
systemRootMenuDisabledText
systemRootMenuSelectedText
systemScrollBarDelimiterActive
systemScrollBarDelimiterInactive
systemSecondaryGroupBoxBackground
systemSecondaryHighlightColor
systemSelectedTabTextColor
systemSheetBackground
systemSheetBackgroundOpaque
systemSheetBackgroundTransparent
systemStaticAreaFill
systemSystemDetailText
systemTabFrontActiveText
systemTabFrontInactiveText
systemTabNonFrontActiveText
systemTabNonFrontInactiveText
systemTabNonFrontPressedText
systemTabPaneBackground
systemToolbarBackground
systemTransparent
systemUtilityWindowBackgroundActive
systemUtilityWindowBackgroundInactive
systemUtilityWindowTitleActiveText
systemUtilityWindowTitleInactiveText
systemWhite
systemWhiteText
systemWindowBody
systemWindowHeaderActiveText
systemWindowHeaderBackground
systemWindowHeaderInactiveText
.DE
.RE
.
The second group of MacOS colors below are based on Apple's "semantic"
NScolors.  On OSX 10.14 (Mojave) and later these colors change value
Tk supports all of the NSColors in the macOS System ColorList.  The
convention for naming these colors is that the Tk name is generated by
capitalizing the macOS name and adding the prefix "system".  On OSX
10.14 (Mojave) and later many of these "semantic" colors will appear
when Dark Mode is enabled.  However, the change is only observable
when the Apple window manager is drawing to the screen. So the
\fBwinfo rgb\fR command will return the color coordinates used in the
standard Aqua mode, even if Dark Mode has been selected in the system
preferences.  The numbered systemWindowBackgroundColors are used in
the \fBttk::notebook\fR and \fBttk::labelframe\fR widgets to provide a
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
contrasting background.  Each numbered color constrasts with its
predecessor.
macOS releases, but newer systems will support additional colors.
.RS
.DS
systemControlAccentColor
systemControlTextColor
systemDisabledControlTextColor
systemLabelColor
systemLinkColor
systemPlaceholderTextColor
systemSelectedTextBackgroundColor
systemSelectedTextColor
systemSeparatorColor
systemTextBackgroundColor
systemTextColor
.DE
.RE
.
The numbered systemWindowBackgroundColors below
are used in the \fBttk::notebook\fR and \fBttk::labelframe\fR widgets
to provide a contrasting background.  Each numbered color constrasts
with its predecessor.
.RS
.DS
systemWindowBackgroundColor
systemWindowBackgroundColor1
systemWindowBackgroundColor2
systemWindowBackgroundColor3
systemWindowBackgroundColor4
systemWindowBackgroundColor5
systemWindowBackgroundColor6
systemWindowBackgroundColor7
.DE
.RE
.TP


\fBWindows\fR
.
On Windows, the following additional system colors are available
(note that the actual color values depend on the currently active OS theme):
.RS
.DS
.ta 6c
system3dDarkShadow	systemHighlight
system3dLight	systemHighlightText
systemActiveBorder	systemInactiveBorder
systemActiveCaption	systemInactiveCaption
systemAppWorkspace	systemInactiveCaptionText
systemBackground	systemInfoBackground
systemButtonFace	systemInfoText
systemButtonHighlight	systemMenu
systemButtonShadow	systemMenuText
system3dDarkShadow	systemHighlightText
system3dLight	systemInactiveBorder
systemActiveBorder	systemInactiveCaption
systemActiveCaption	systemInactiveCaptionText
systemAppWorkspace	systemInfoBackground
systemBackground	systemInfoText
systemButtonFace	systemMenu
systemButtonHighlight	systemMenuText
systemButtonShadow	systemPlaceholderText
systemButtonText	systemScrollbar
systemCaptionText	systemWindow
systemDisabledText	systemWindowFrame
systemGrayText	systemWindowText
systemHighlight
.DE
.RE
.SH "SEE ALSO"
options(n), Tk_GetColor(3)
.SH KEYWORDS
color, option
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/console.n.

19
20
21
22
23
24
25
26

27
28
29
30






31
32
33
34
35
36
37
19
20
21
22
23
24
25

26
27



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







-
+

-
-
-
+
+
+
+
+
+







and output on the standard I/O channels on platforms that do not have
a real console.  It is implemented as a separate interpreter with the
Tk toolkit loaded, and control over this interpreter is given through
the \fBconsole\fR command.  The behaviour of the console window is
defined mainly through the contents of the \fIconsole.tcl\fR file in
the Tk library. Except for TkAqua, this command is not available when
Tk is loaded into a tclsh interpreter with
.QW "\fBpackage require Tk\fR" ,
.QW "\fBpackage require tk\fR" ,
as a conventional terminal is expected to be present in that case.
In TkAqua, this command is only available when stdin is \fB/dev/null\fR
(as is the case e.g. when the application embedding Tk is started
from the Mac OS X Finder).
In TkAqua, this command is disabled when there is a startup script
and stdin is \fB/dev/null\fR (as is the case e.g. when a bundled application
embedding Tk is started by the macOS Launcher).  To enable the command
in that case, define the environment variable \fBTK_CONSOLE\fR.  This can be
done by modifying the Info.plist file by adding the LSEnvironment key
to the main dict and setting its value to be a dict with the key \fBTK_CONSOLE\fR.
.PP
.TP
\fBconsole eval \fIscript\fR
Evaluate the \fIscript\fR argument as a Tcl script in the console
interpreter.  The normal interpreter is accessed through the
\fBconsoleinterp\fR command in the console interpreter.
.TP

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 <[email protected]>
'\"
.TH cursors n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS

Changes to doc/entry.n.

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







-
+







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 arg ...\fR?
\fIpathName subcommand \fR?\fIarg ...\fR?
.CE
\fISubcommand\fR and the \fIarg\fRs
determine the exact behavior of the command.
.SS INDICES
.PP
Many of the widget commands for entries take one or more indices as
arguments.  An index specifies a particular character in the entry's
399
400
401
402
403
404
405
406


407
408
409
410
411
412
413
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413
414







-
+
+







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.
\fINumber\fR must be an integer or a float, but if it is a float then
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR or an abbreviation
of one of these.
If \fIwhat\fR is \fBpages\fR then the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then characters farther to the left become
visible;  if it is positive then characters farther to the right
become visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by

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 arg ...\fR?
\fBevent\fI option \fR?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
The \fBevent\fR command provides several facilities for dealing with
window system events, such as defining virtual events and synthesizing
events.  The command has several different forms, determined by the
first argument.  The following forms are currently supported:

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 arg ...\fR?
\fBfocus \fIoption\fR ?\fIarg ...\fR?
.fi
.BE
.SH DESCRIPTION
.PP
The \fBfocus\fR command is used to manage the Tk input focus.
At any given time, one window on each display is designated as
the \fIfocus window\fR;  any key press or key release events for the

Changes to doc/font.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 font n 8.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
font \- Create and inspect fonts.
.SH SYNOPSIS
\fBfont\fI option \fR?\fIarg arg ...\fR?
\fBfont\fI option \fR?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
The \fBfont\fR command provides several facilities for dealing with
fonts, such as defining named fonts and inspecting the actual attributes of
a font.  The command has several different forms, determined by the
first argument.  The following forms are currently supported:

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
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
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) 2008 Daniel A. Steffen <[email protected]>
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH fontchooser n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
fontchooser \- control font selection dialog
.SH SYNOPSIS
\fBtk fontchooser\fR \fBconfigure\fR ?\fI\-option value \-option value ...\fR?
\fBtk fontchooser\fR \fBconfigure\fR ?\fI\-option value ...\fR?
.sp
\fBtk fontchooser\fR \fBshow\fR
.sp
\fBtk fontchooser\fR \fBhide\fR
.BE
.SH DESCRIPTION
.PP
The \fBtk fontchooser\fR command controls the Tk font selection dialog. It uses
the native platform font selection dialog where available, or a dialog
implemented in Tcl otherwise.
.PP
Unlike most of the other Tk dialog commands, \fBtk fontchooser\fR does not
return an immediate result, as on some platforms (Mac OS X) the standard font
dialog is modeless while on others (Windows) it is modal. To accommodate this
difference, all user interaction with the dialog will be communicated to the
caller via callbacks or virtual events.
.PP
The \fBtk fontchooser\fR command can have one of the following forms:
.TP
\fBtk fontchooser\fR \fBconfigure \fR?\fI\-option value \-option value ...\fR?
\fBtk fontchooser\fR \fBconfigure \fR?\fI\-option value ...\fR?
.
Set or query one or more of the configurations options below (analogous to Tk
widget configuration).
.TP
\fBtk fontchooser\fR \fBshow\fR
.
Show the font selection dialog. Depending on the platform, may return

Changes to doc/frame.n.

116
117
118
119
120
121
122
123

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

139
140
141
142
143
144
145
116
117
118
119
120
121
122

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

138
139
140
141
142
143
144
145







-
+














-
+







.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 arg ...\fR?
\fIpathName option \fR?\fIarg ...\fR?
.CE
.PP
\fIPathName\fR is the name of the command, which is the same as
the frame widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for frame widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBframe\fR
command.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? \fI?value option value ...\fR?
\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

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 arg \fR...?
\fBgrab \fIoption \fR?\fIarg \fR...?
.BE
.SH DESCRIPTION
.PP
This command implements simple pointer and keyboard grabs for Tk.
Tk's grabs are different than the grabs
described in the Xlib documentation.
When a grab is set for a particular window, Tk restricts all pointer

Changes to doc/grid.n.

13
14
15
16
17
18
19
20

21
22
23
24

25
26

27
28
29
30
31
32

33
34

35
36
37
38

39
40
41
42
43

44
45
46
47
48
49
50
51

52
53
54

55
56
57
58
59
60
61
62



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

84
85
86
87
88

89
90

91
92

93
94
95

96
97
98
99
100
101
102

103
104

105
106
107
108


109
110
111
112
113
114

115
116
117
118
119

120
121
122


123
124
125
126
127
128
129


130
131
132
133
134
135
136
137


138
139
140
141
142
143

144
145
146
147

148
149
150
151
152

153
154
155
156

157
158
159
160

161
162

163
164

165
166
167
168

169
170
171


172
173
174
175
176
177


178
179
180
181
182

183
184
185

186
187
188
189
190

191
192

193
194
195
196
197

198
199
200
201



202
203

204
205
206
207
208
209



210
211

212
213
214

215
216
217

218
219
220
221


222
223

224
225

226
227
228
229
230

231
232
233

234
235
236

237
238
239
240

241
242
243

244
245
246

247
248
249
250
251
252
253
254



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

276
277
278
279
280

281
282
283
284



285
286

287
288

289
290
291
292
293



294
295

296
297
298

299
300
301


302
303
304
305

306
307
308


309
310

311




312
313
314
315
316

317
318
319

320
321
322
323
324



325
326

327
328
329
330
331

332
333

334
335
336
337
338
339


340
341
342
343

344
345

346
347
348
349
350


351
352

353
354

355
356

357
358
359
360

361
362
363

364
365

366
367

368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388

389
390

391
392

393
394
395
396
397
398
399
400
401
402



403
404
405
406
407

408
409
410


411
412

413
414
415


416
417
418
419



420
421
422
423
424
425
426
427






428
429
430
431
432
433
434
13
14
15
16
17
18
19

20
21
22
23

24
25

26
27
28
29
30
31

32
33

34
35
36
37

38
39
40
41
42

43
44
45
46
47
48
49
50

51
52
53

54
55
56
57
58
59



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

83
84
85
86
87

88
89

90
91

92
93
94

95
96
97
98
99
100
101

102
103

104
105
106


107
108
109
110
111
112
113

114
115
116
117
118

119
120


121
122
123
124
125
126
127


128
129
130
131
132
133
134
135


136
137
138
139
140
141
142

143
144
145
146

147
148
149
150
151

152
153
154
155

156
157
158
159

160
161

162
163

164
165
166
167

168
169


170
171
172
173
174
175


176
177
178
179
180
181

182
183
184

185
186
187
188
189

190
191

192
193
194
195
196

197
198



199
200
201
202

203
204
205
206



207
208
209
210

211
212
213

214
215
216

217
218
219


220
221
222

223
224

225
226
227
228
229

230
231
232

233
234
235

236
237
238
239

240
241
242

243
244
245

246
247
248
249
250
251



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

275
276
277
278
279

280
281



282
283
284
285

286


287
288
289



290
291
292
293

294
295
296

297
298


299
300
301
302
303

304
305


306
307
308

309
310
311
312
313
314
315
316
317
318

319
320
321

322
323
324



325
326
327
328

329
330
331
332
333

334
335

336
337
338
339
340


341
342
343
344
345

346
347

348
349
350
351


352
353
354

355
356

357
358

359
360
361
362

363
364
365

366
367

368
369

370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390

391
392

393
394

395
396
397
398
399
400
401
402



403
404
405
406
407
408
409

410
411


412
413
414

415
416


417
418
419



420
421
422
423
424






425
426
427
428
429
430
431
432
433
434
435
436
437







-
+



-
+

-
+





-
+

-
+



-
+




-
+







-
+


-
+





-
-
-
+
+
+




















-
+




-
+

-
+

-
+


-
+






-
+

-
+


-
-
+
+





-
+




-
+

-
-
+
+





-
-
+
+






-
-
+
+





-
+



-
+




-
+



-
+



-
+

-
+

-
+



-
+

-
-
+
+




-
-
+
+




-
+


-
+




-
+

-
+




-
+

-
-
-
+
+
+

-
+



-
-
-
+
+
+

-
+


-
+


-
+


-
-
+
+

-
+

-
+




-
+


-
+


-
+



-
+


-
+


-
+





-
-
-
+
+
+




















-
+




-
+

-
-
-
+
+
+

-
+
-
-
+


-
-
-
+
+
+

-
+


-
+

-
-
+
+



-
+

-
-
+
+

-
+

+
+
+
+




-
+


-
+


-
-
-
+
+
+

-
+




-
+

-
+




-
-
+
+



-
+

-
+



-
-
+
+

-
+

-
+

-
+



-
+


-
+

-
+

-
+




















-
+

-
+

-
+







-
-
-
+
+
+




-
+

-
-
+
+

-
+

-
-
+
+

-
-
-
+
+
+


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







.SH SYNOPSIS
\fBgrid \fIoption arg \fR?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
The \fBgrid\fR command is used to communicate with the grid
geometry manager that arranges widgets in rows and columns inside
of another window, called the geometry master (or master window).
of another window, called the geometry container (or container window).
The \fBgrid\fR command can have any of several forms, depending
on the \fIoption\fR argument:
.TP
\fBgrid \fIslave \fR?\fIslave ...\fR? ?\fIoptions\fR?
\fBgrid \fIwindow \fR?\fIwindow ...\fR? ?\fIoptions\fR?
.
If the first argument to \fBgrid\fR is suitable as the first slave
If the first argument to \fBgrid\fR is suitable as the first window
argument to \fBgrid configure\fR, either a window name (any value
starting with \fB.\fR) or one of the characters \fBx\fR or \fB^\fR
(see the \fBRELATIVE PLACEMENT\fR section below), then the command is
processed in the same way as \fBgrid configure\fR.
.TP
\fBgrid anchor \fImaster\fR ?\fIanchor\fR?
\fBgrid anchor \fIwindow\fR ?\fIanchor\fR?
.
The anchor value controls how to place the grid within the master
The anchor value controls how to place the grid within the container window
when no row/column has any weight.  See \fBTHE GRID ALGORITHM\fR below
for further details.  The default \fIanchor\fR is \fInw\fR.
.TP
\fBgrid bbox \fImaster\fR ?\fIcolumn row\fR? ?\fIcolumn2 row2\fR?
\fBgrid bbox \fIwindow\fR ?\fIcolumn row\fR? ?\fIcolumn2 row2\fR?
.
With no arguments,
the bounding box (in pixels) of the grid is returned.
The return value consists of 4 integers.  The first two are the pixel
offset from the master window (x then y) of the top-left corner of the
offset from the container window (x then y) of the top-left corner of the
grid, and the second two integers are the width and height of the grid,
also in pixels.  If a single \fIcolumn\fR and \fIrow\fR is specified on
the command line, then the bounding box for that cell is returned, where the
top left cell is numbered from zero.  If both \fIcolumn\fR and \fIrow\fR
arguments are specified, then the bounding box spanning the rows and columns
indicated is returned.
.TP
\fBgrid columnconfigure \fImaster index \fR?\fI\-option value...\fR?
\fBgrid columnconfigure \fIwindow index \fR?\fI\-option value...\fR?
.
Query or set the column properties of the \fIindex\fR column of the
geometry master, \fImaster\fR.
geometry container, \fIwindow\fR.
The valid options are \fB\-minsize\fR, \fB\-weight\fR, \fB\-uniform\fR
and \fB\-pad\fR.
If one or more options are provided, then \fIindex\fR may be given as
a list of column indices to which the configuration options will operate on.
Indices may be integers, window names or the keyword \fIall\fR. For \fIall\fR
the options apply to all columns currently occupied be slave windows. For
a window name, that window must be a slave of this master and the options
apply to all columns currently occupied be the slave.
the options apply to all columns currently occupied be content windows. For
a window name, that window must be a content of this container and the options
apply to all columns currently occupied be the content.
The \fB\-minsize\fR option sets the minimum size, in screen units,
that will be permitted for this column.
The \fB\-weight\fR option (an integer value)
sets the relative weight for apportioning
any extra spaces among
columns.
A weight of zero (0) indicates the column will not deviate from its requested
size.  A column whose weight is two will grow at twice the rate as a column
of weight one when extra space is allocated to the layout.
The \fB\-uniform\fR option, when a non-empty value is supplied, places
the column in a \fIuniform group\fR with other columns that have the
same value for \fB\-uniform\fR.  The space for columns belonging to a
uniform group is allocated so that their sizes are always in strict
proportion to their \fB\-weight\fR values.  See
\fBTHE GRID ALGORITHM\fR below for further details.
The \fB\-pad\fR option specifies the number of screen units that will be
added to the largest window contained completely in that column when the
grid geometry manager requests a size from the containing window.
If only an option is specified, with no value,
the current value of that option is returned.
If only the master window and index is specified, all the current settings
If only the container window and index is specified, all the current settings
are returned in a list of
.QW "\-option value"
pairs.
.TP
\fBgrid configure \fIslave \fR?\fIslave ...\fR? ?\fIoptions\fR?
\fBgrid configure \fIwindow \fR?\fIwindow ...\fR? ?\fIoptions\fR?
.
The arguments consist of the names of one or more slave windows
The arguments consist of the names of one or more content windows
followed by pairs of arguments that specify how
to manage the slaves.
to manage the content.
The characters \fB\-\fR,  \fBx\fR and \fB^\fR,
can be specified instead of a window name to alter the default
location of a \fIslave\fR, as described in the \fBRELATIVE PLACEMENT\fR
location of a \fIwindow\fR, as described in the \fBRELATIVE PLACEMENT\fR
section, below.
The following options are supported:
.RS
.TP
\fB\-column \fIn\fR
.
Insert the slave so that it occupies the \fIn\fRth column in the grid.
Insert the window so that it occupies the \fIn\fRth column in the grid.
Column numbers start with 0.  If this option is not supplied, then the
slave is arranged just to the right of previous slave specified on this
window is arranged just to the right of previous window specified on this
call to \fBgrid\fR, or column
.QW 0
if it is the first slave.  For each
\fBx\fR that immediately precedes the \fIslave\fR, the column position
if it is the first window.  For each
\fBx\fR that immediately precedes the \fIwindow\fR, the column position
is incremented by one.  Thus the \fBx\fR represents a blank column
for this row in the grid.
.TP
\fB\-columnspan \fIn\fR
.
Insert the slave so that it occupies \fIn\fR columns in the grid.
Insert the window so that it occupies \fIn\fR columns in the grid.
The default is one column, unless the window name is followed by a
\fB\-\fR, in which case the columnspan is incremented once for each immediately
following \fB\-\fR.
.TP
\fB\-in \fIother\fR
\fB\-in \fIcontainer\fR
.
Insert the slave(s) in the master
window given by \fIother\fR.  The default is the first slave's
Insert the window(s) in the container
window given by \fIcontainer\fR.  The default is the first window's
parent window.
.TP
\fB\-ipadx \fIamount\fR
.
The \fIamount\fR specifies how much horizontal internal padding to
leave on each side of the slave(s).  This is space is added
inside the slave(s) border.
leave on each side of the content.  This is space is added
inside the content border.
The \fIamount\fR must be a valid screen distance, such as \fB2\fR or \fB.5c\fR.
It defaults to 0.
.TP
\fB\-ipady \fIamount\fR
.
The \fIamount\fR specifies how much vertical internal padding to
leave on the top and bottom of the slave(s).
This space is added inside the slave(s) border.
leave on the top and bottom of the content.
This space is added inside the content border.
The \fIamount\fR  defaults to 0.
.TP
\fB\-padx \fIamount\fR
.
The \fIamount\fR specifies how much horizontal external padding to
leave on each side of the slave(s), in screen units.
leave on each side of the content, in screen units.
\fIAmount\fR may be a list
of two values to specify padding for left and right separately.
The \fIamount\fR defaults to 0.
This space is added outside the slave(s) border.
This space is added outside the content border.
.TP
\fB\-pady \fIamount\fR
.
The \fIamount\fR specifies how much vertical external padding to
leave on the top and bottom of the slave(s), in screen units.
leave on the top and bottom of the content, in screen units.
\fIAmount\fR may be a list
of two values to specify padding for top and bottom separately.
The \fIamount\fR defaults to 0.
This space is added outside the slave(s) border.
This space is added outside the content border.
.TP
\fB\-row \fIn\fR
.
Insert the slave so that it occupies the \fIn\fRth row in the grid.
Insert the content so that it occupies the \fIn\fRth row in the grid.
Row numbers start with 0.  If this option is not supplied, then the
slave is arranged on the same row as the previous slave specified on this
content is arranged on the same row as the previous content specified on this
call to \fBgrid\fR, or the next row after the highest occupied row
if this is the first slave.
if this is the first content.
.TP
\fB\-rowspan \fIn\fR
.
Insert the slave so that it occupies \fIn\fR rows in the grid.
Insert the content so that it occupies \fIn\fR rows in the grid.
The default is one row.  If the next \fBgrid\fR command contains
\fB^\fR characters instead of \fIslaves\fR that line up with the columns
of this \fIslave\fR, then the \fBrowspan\fR of this \fIslave\fR is
\fB^\fR characters instead of \fIcontent\fR that line up with the columns
of this \fIcontent\fR, then the \fBrowspan\fR of this \fIcontent\fR is
extended by one.
.TP
\fB\-sticky \fIstyle\fR
.
If a slave's cell is larger than its requested dimensions, this
option may be used to position (or stretch) the slave within its cell.
If a content's cell is larger than its requested dimensions, this
option may be used to position (or stretch) the content within its cell.
\fIStyle\fR  is a string that contains zero or more of the characters
\fBn\fR, \fBs\fR, \fBe\fR or \fBw\fR.
The string can optionally contain spaces or
commas, but they are ignored.  Each letter refers to a side (north, south,
east, or west) that the slave will
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 slave will be stretched to fill the entire
specified, the content will be stretched to fill the entire
height (or width) of its cavity.  The \fB\-sticky\fR option subsumes the
combination of \fB\-anchor\fR and \fB\-fill\fR that is used by \fBpack\fR.
The default is
.QW "" ,
which causes the slave to be centered in its cavity, at its requested size.
which causes the content to be centered in its cavity, at its requested size.
.LP
If any of the slaves are already managed by the geometry manager
If any of the content is already managed by the geometry manager
then any unspecified options for them retain their previous values rather
than receiving default values.
.RE
.TP
\fBgrid forget \fIslave \fR?\fIslave ...\fR?
\fBgrid forget \fIwindow \fR?\fIwindow ...\fR?
.
Removes each of the \fIslave\fRs from grid for its
master and unmaps their windows.
The slaves will no longer be managed by the grid geometry manager.
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
slave is managed once more by the grid geometry manager, the initial
window is managed once more by the grid geometry manager, the initial
default settings are used.
.RS
.PP
.VS TIP518
If the last slave of the master becomes unmanaged, this will also send
the virtual event \fB<<NoManagedChild>>\fR to the master; the master
.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 TIP518
.VE "TIP 518"
.RE
.TP
\fBgrid info \fIslave\fR
\fBgrid info \fIwindow\fR
.
Returns a list whose elements are the current configuration state of
the slave given by \fIslave\fR in the same option-value form that
the content given by \fIwindow\fR in the same option-value form that
might be specified to \fBgrid configure\fR.
The first two elements of the list are
.QW "\fB\-in \fImaster\fR"
where \fImaster\fR is the slave's master.
.QW "\fB\-in \fIcontainer\fR"
where \fIcontainer\fR is the windows's container window.
.TP
\fBgrid location \fImaster x y\fR
\fBgrid location \fIwindow x y\fR
.
Given  \fIx\fR and \fIy\fR values in screen units relative to the master window,
Given  \fIx\fR and \fIy\fR values in screen units relative to the container window,
the column and row number at that \fIx\fR and \fIy\fR location is returned.
For locations that are above or to the left of the grid, \fB\-1\fR is
returned.
.TP
\fBgrid propagate \fImaster\fR ?\fIboolean\fR?
\fBgrid propagate \fIwindow\fR ?\fIboolean\fR?
.
If \fIboolean\fR has a true boolean value such as \fB1\fR or \fBon\fR
then propagation is enabled for \fImaster\fR, which must be a window
then propagation is enabled for \fIwindow\fR, which must be a window
name (see \fBGEOMETRY PROPAGATION\fR below).
If \fIboolean\fR has a false boolean value then propagation is
disabled for \fImaster\fR.
disabled for \fIwindow\fR.
In either of these cases an empty string is returned.
If \fIboolean\fR is omitted then the command returns \fB0\fR or
\fB1\fR to indicate whether propagation is currently enabled
for \fImaster\fR.
for \fIwindow\fR.
Propagation is enabled by default.
.TP
\fBgrid rowconfigure \fImaster index \fR?\fI\-option value...\fR?
\fBgrid rowconfigure \fIwindow index \fR?\fI\-option value...\fR?
.
Query or set the row properties of the \fIindex\fR row of the
geometry master, \fImaster\fR.
geometry container, \fIwindow\fR.
The valid options are \fB\-minsize\fR, \fB\-weight\fR, \fB\-uniform\fR
and \fB\-pad\fR.
If one or more options are provided, then \fIindex\fR may be given as
a list of row indices to which the configuration options will operate on.
Indices may be integers, window names or the keyword \fIall\fR. For \fIall\fR
the options apply to all rows currently occupied be slave windows. For
a window name, that window must be a slave of this master and the options
apply to all rows currently occupied be the slave.
the options apply to all rows currently occupied by content windows. For
a window name, that window must be a content window of this container and the options
apply to all rows currently occupied by the container window.
The \fB\-minsize\fR option sets the minimum size, in screen units,
that will be permitted for this row.
The \fB\-weight\fR option (an integer value)
sets the relative weight for apportioning
any extra spaces among
rows.
A weight of zero (0) indicates the row will not deviate from its requested
size.  A row whose weight is two will grow at twice the rate as a row
of weight one when extra space is allocated to the layout.
The \fB\-uniform\fR option, when a non-empty value is supplied, places
the row in a \fIuniform group\fR with other rows that have the
same value for \fB\-uniform\fR.  The space for rows belonging to a
uniform group is allocated so that their sizes are always in strict
proportion to their \fB\-weight\fR values.  See
\fBTHE GRID ALGORITHM\fR below for further details.
The \fB\-pad\fR option specifies the number of screen units that will be
added to the largest window contained completely in that row when the
grid geometry manager requests a size from the containing window.
If only an option is specified, with no value,
the current value of that option is returned.
If only the master window and index is specified, all the current settings
If only the container window and index is specified, all the current settings
are returned in a list of
.QW "-option value"
pairs.
.TP
\fBgrid remove \fIslave \fR?\fIslave ...\fR?
\fBgrid remove \fIwindow \fR?\fIwindow ...\fR?
.
Removes each of the \fIslave\fRs from grid for its
master and unmaps their windows.
The slaves will no longer be managed by the grid geometry manager.
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
so that if the content window is managed once more by the grid
slave is managed once more by the grid geometry manager, the previous
values are retained.
geometry manager, the previous values are retained.
.RS
.PP
.VS TIP518
If the last slave of the master becomes unmanaged, this will also send
the virtual event \fB<<NoManagedChild>>\fR to the master; the master
.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 TIP518
.VE "TIP 518"
.RE
.TP
\fBgrid size \fImaster\fR
\fBgrid size \fIcontainer\fR
.
Returns the size of the grid (in columns then rows) for \fImaster\fR.
The size is determined either by the \fIslave\fR occupying the largest
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 slaves \fImaster\fR ?\fI\-option value\fR?
\fBgrid content \fIwindow\fR ?\fI\-option value\fR?
.
If no options are supplied, a list of all of the slaves in \fImaster\fR
are returned, most recently manages first.
If no options are supplied, a list of all of the content in \fIwindow\fR
is returned, most recently managed first.
\fIOption\fR can be either \fB\-row\fR or \fB\-column\fR which
causes only the slaves in the row (or column) specified by \fIvalue\fR
causes only the content in the row (or column) specified by \fIvalue\fR
to be returned.
.TP
\fBgrid slaves \fIwindow\fR ?\fI\-option value\fR?
.
Synonym for . \fBgrid content \fIwindow\fR ?\fI\-option value\fR?
.SH "RELATIVE PLACEMENT"
.PP
The \fBgrid\fR command contains a limited set of capabilities that
permit layouts to be created without specifying the row and column
information for each slave.  This permits slaves to be rearranged,
information for each content.  This permits content to be rearranged,
added, or removed without the need to explicitly specify row and
column information.
When no column or row information is specified for a \fIslave\fR,
When no column or row information is specified for a \fIcontent\fR,
default values are chosen for
\fB\-column\fR, \fB\-row\fR, \fB\-columnspan\fR and \fB\-rowspan\fR
at the time the \fIslave\fR is managed. The values are chosen
based upon the current layout of the grid, the position of the \fIslave\fR
relative to other \fIslave\fRs in the same grid command, and the presence
at the time the \fIcontent\fR is managed. The values are chosen
based upon the current layout of the grid, the position of the \fIcontent\fR
relative to other \fIcontent\fRs in the same grid command, and the presence
of the characters \fB\-\fR, \fBx\fR, and \fB^\fR in \fBgrid\fR
command where \fIslave\fR names are normally expected.
command where \fIcontent\fR names are normally expected.
.RS
.TP
\fB\-\fR
.
This increases the \fB\-columnspan\fR of the \fIslave\fR to the left.  Several
This increases the \fB\-columnspan\fR of the \fIcontent\fR to the left.  Several
\fB\-\fR's in a row will successively increase the number of columns spanned. A \fB\-\fR
may not follow a \fB^\fR or a \fBx\fR, nor may it be the first \fIslave\fR
may not follow a \fB^\fR or a \fBx\fR, nor may it be the first \fIcontent\fR
argument to \fBgrid configure\fR.
.TP
\fBx\fR
.
This leaves an empty column between the \fIslave\fR on the left and
the \fIslave\fR on the right.
This leaves an empty column between the \fIcontent\fR on the left and
the \fIcontent\fR on the right.
.TP
\fB^\fR
.
This extends the \fB\-rowspan\fR of the \fIslave\fR above the \fB^\fR's
This extends the \fB\-rowspan\fR of the \fIcontent\fR above the \fB^\fR's
in the grid.  The number of \fB^\fR's in a row must match the number of
columns spanned by the \fIslave\fR above it.
columns spanned by the \fIcontent\fR above it.
.RE
.SH "THE GRID ALGORITHM"
.PP
The grid geometry manager lays out its slaves in three steps.
In the first step, the minimum size needed to fit all of the slaves
The grid geometry manager lays out its content in three steps.
In the first step, the minimum size needed to fit all of the content
is computed, then (if propagation is turned on), a request is made
of the master window to become that size.
of the container window to become that size.
In the second step, the requested size is compared against the actual size
of the master.  If the sizes are different, then spaces is added to or taken
of the container.  If the sizes are different, then spaces is added to or taken
away from the layout as needed.
For the final step, each slave is positioned in its row(s) and column(s)
For the final step, each content is positioned in its row(s) and column(s)
based on the setting of its \fIsticky\fR flag.
.PP
To compute the minimum size of a layout, the grid geometry manager
first looks at all slaves whose \fB\-columnspan\fR and \fB\-rowspan\fR values are one,
first looks at all content whose \fB\-columnspan\fR and \fB\-rowspan\fR values are one,
and computes the nominal size of each row or column to be either the
\fIminsize\fR for that row or column, or the sum of the \fIpad\fRding
plus the size of the largest slave, whichever is greater.  After that
plus the size of the largest content, whichever is greater.  After that
the rows or columns in each uniform group adapt to each other.  Then
the slaves whose row-spans or column-spans are greater than one are
the content whose row-spans or column-spans are greater than one are
examined.  If a group of rows or columns need to be increased in size
in order to accommodate these slaves, then extra space is added to each
in order to accommodate these content, then extra space is added to each
row or column in the group according to its \fIweight\fR.  For each
group whose weights are all zero, the additional space is apportioned
equally.
.PP
When multiple rows or columns belong to a uniform group, the space
allocated to them is always in proportion to their weights. (A weight
of zero is considered to be 1.)  In other words, a row or column
configured with \fB\-weight 1 \-uniform a\fR will have exactly the same
size as any other row or column configured with \fB\-weight 1 \-uniform
a\fR.  A row or column configured with \fB\-weight 2 \-uniform b\fR will
be exactly twice as large as one that is configured with \fB\-weight 1
\-uniform b\fR.
.PP
More technically, each row or column in the group will have a size
equal to \fIk*weight\fR for some constant \fIk\fR.  The constant
\fIk\fR is chosen so that no row or column becomes smaller than its
minimum size.  For example, if all rows or columns in a group have the
same weight, then each row or column will have the same size as the
largest row or column in the group.
.PP
For masters whose size is larger than the requested layout, the additional
For containers whose size is larger than the requested layout, the additional
space is apportioned according to the row and column weights.  If all of
the weights are zero, the layout is placed within its master according to
the weights are zero, the layout is placed within its container according to
the \fIanchor\fR value.
For masters whose size is smaller than the requested layout, space is taken
For containers whose size is smaller than the requested layout, space is taken
away from columns and rows according to their weights.  However, once a
column or row shrinks to its minsize, its weight is taken to be zero.
If more space needs to be removed from a layout than would be permitted, as
when all the rows or columns are at their minimum sizes, the layout is
placed and clipped according to the \fIanchor\fR value.
.SH "GEOMETRY PROPAGATION"
.PP
The grid geometry manager normally computes how large a master must be to
just exactly meet the needs of its slaves, and it sets the
requested width and height of the master to these dimensions.
The grid geometry manager normally computes how large a container must be to
just exactly meet the needs of its content, and it sets the
requested width and height of the container to these dimensions.
This causes geometry information to propagate up through a
window hierarchy to a top-level window so that the entire
sub-tree sizes itself to fit the needs of the leaf windows.
However, the \fBgrid propagate\fR command may be used to
turn off propagation for one or more masters.
turn off propagation for one or more containers.
If propagation is disabled then grid will not set
the requested width and height of the master window.
This may be useful if, for example, you wish for a master
the requested width and height of the container window.
This may be useful if, for example, you wish for a container
window to have a fixed size that you specify.
.SH "RESTRICTIONS ON MASTER WINDOWS"
.SH "RESTRICTIONS ON CONTAINER WINDOWS"
.PP
The master for each slave must either be the slave's parent
(the default) or a descendant of the slave's parent.
The container for each content must either be the content's parent
(the default) or a descendant of the content's parent.
This restriction is necessary to guarantee that the
slave can be placed over any part of its master that is
visible without danger of the slave being clipped by its parent.
In addition, all slaves in one call to \fBgrid\fR must have the same master.
content can be placed over any part of its container that is
visible without danger of the content being clipped by its parent.
In addition, all content in one call to \fBgrid\fR must have the same container.
.SH "STACKING ORDER"
.PP
If the master for a slave is not its parent then you must make sure
that the slave is higher in the stacking order than the master.
Otherwise the master will obscure the slave and it will appear as
if the slave has not been managed correctly.
The easiest way to make sure the slave is higher than the master is
to create the master window first:  the most recently created window
If the container for a content is not its parent then you must make sure
that the content is higher in the stacking order than the container.
Otherwise the container will obscure the content and it will appear as
if the content has not been managed correctly.
The easiest way to make sure the content is higher than the container is
to create the container window first:  the most recently created window
will be highest in the stacking order.
.SH CREDITS
.PP
The \fBgrid\fR command is based on ideas taken from the \fIGridBag\fR
geometry manager written by Doug. Stein, and the \fBblt_table\fR geometry
manager, written by George Howlett.
.SH EXAMPLES

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 arg ...\fR?
\fBimage\fR \fIoption \fR?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
The \fBimage\fR command is used to create, delete, and query images.
It can take several different forms, depending on the
\fIoption\fR argument.  The legal forms are:
.TP

Changes to doc/keysyms.n.

1
2

3
4
5
6
7
8
9
10
11
12
13
14
15

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

28
29
30


31
32
33
34




35
36
37
38
39
40





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

53
54
55

56

57

58
59
60
61
62
63
64
65
1

2
3
4
5
6
7
8
9
10
11
12
13
14

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

27
28
29
30
31
32




33
34
35
36






37
38
39
40
41

42
43
44
45
46
47
48
49
50
51

52
53
54

55
56
57

58

59
60
61
62
63
64
65

-
+












-
+











-
+



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










-
+


-
+

+
-
+
-







'\"
'\" Copyright (c) 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
keysyms \- keysyms recognized by Tk
.BE
.SH DESCRIPTION
.PP
Tk recognizes many keysyms when specifying key bindings (e.g.,
.QW "\fBbind\fR \fB. <Key-\fR\fIkeysym\fR\fB>\fR" ).
.QW "\fBbind\fR \fB. <\fR\fIkeysym\fR\fB>\fR" ).
The following list enumerates the
keysyms that will be recognized by Tk.  Note that not all keysyms will
be valid on all platforms, and some keysyms are also available on
platforms that have a different native name for that key.
For example, on Unix systems, the presence
of a particular keysym is dependent on the configuration of the
keyboard modifier map.  This list shows keysyms along with their
decimal and hexadecimal values.
.PP
.CS
space                               32     0x20
exclam                              33     0x21
! (exclam)                          33     0x21
quotedbl                            34     0x22
numbersign                          35     0x23
dollar                              36     0x24
% (percent)                         37     0x25
& (ampersand)                       38     0x26
percent                             37     0x25
ampersand                           38     0x26
apostrophe                          39     0x27
parenleft                           40     0x28
' (apostrophe)                      39     0x27
( (parenleft)                       40     0x28
) (parenright)                      41     0x29
* (asterisk)                        42     0x2A
parenright                          41     0x29
asterisk                            42     0x2A
plus                                43     0x2B
comma                               44     0x2C
minus                               45     0x2D
period                              46     0x2E
+ (plus)                            43     0x2B
, (comma)                           44     0x2C
minus                               45     0x2D
. (period)                          46     0x2E
/ (slash)                           47     0x2F
slash                               47     0x2F
0                                   48     0x30
1                                   49     0x31
2                                   50     0x32
3                                   51     0x33
4                                   52     0x34
5                                   53     0x35
6                                   54     0x36
7                                   55     0x37
8                                   56     0x38
9                                   57     0x39
colon                               58     0x3A
: (colon)                           58     0x3A
semicolon                           59     0x3B
less                                60     0x3C
equal                               61     0x3D
= (equal)                           61     0x3D
greater                             62     0x3E
? (question)                        63     0x3F
question                            63     0x3F
@ (at)                              64     0x40
at                                  64     0x40
A                                   65     0x41
B                                   66     0x42
C                                   67     0x43
D                                   68     0x44
E                                   69     0x45
F                                   70     0x46
G                                   71     0x47
81
82
83
84
85
86
87
88
89



90
91
92
93
94
95
96
97
81
82
83
84
85
86
87


88
89
90

91
92
93
94
95
96
97







-
-
+
+
+
-







W                                   87     0x57
X                                   88     0x58
Y                                   89     0x59
Z                                   90     0x5A
bracketleft                         91     0x5B
backslash                           92     0x5C
bracketright                        93     0x5D
asciicircum                         94     0x5E
underscore                          95     0x5F
^ (asciicircum)                     94     0x5E
_ (underscore)                      95     0x5F
` (grave)                           96     0x60
grave                               96     0x60
a                                   97     0x61
b                                   98     0x62
c                                   99     0x63
d                                  100     0x64
e                                  101     0x65
f                                  102     0x66
g                                  103     0x67
111
112
113
114
115
116
117
118

119
120

121
122
123
124
125



126
127
128
129
130
131
132
133









134
135
136
137


138
139
140
141
142
143





144
145
146
147



148
149

150
151
152
153
154
155










156
157
158
159
160
161





162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
















177
178

179
180
181
182
183
184
185







186
187
188
189
190
191
192
193








194
195
196
197
198






199
200
201
202
203




204
205
206
207
208
209
210
211
212
213
214
215
216
















217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
111
112
113
114
115
116
117

118
119

120
121




122
123
124








125
126
127
128
129
130
131
132
133
134



135
136






137
138
139
140
141




142
143
144


145






146
147
148
149
150
151
152
153
154
155






156
157
158
159
160















161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176


177







178
179
180
181
182
183
184








185
186
187
188
189
190
191
192





193
194
195
196
197
198





199
200
201
202













203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227


228
229
230
231
232
233
234







-
+

-
+

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

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









-
-







u                                  117     0x75
v                                  118     0x76
w                                  119     0x77
x                                  120     0x78
y                                  121     0x79
z                                  122     0x7A
braceleft                          123     0x7B
bar                                124     0x7C
| (bar)                            124     0x7C
braceright                         125     0x7D
asciitilde                         126     0x7E
~ (asciitilde)                     126     0x7E
nobreakspace                       160     0xA0
exclamdown                         161     0xA1
cent                               162     0xA2
sterling                           163     0xA3
currency                           164     0xA4
\(r! (exclamdown)                     161     0xA1
\(ct (cent)                           162     0xA2
\(Po (sterling)                       163     0xA3
yen                                165     0xA5
brokenbar                          166     0xA6
section                            167     0xA7
diaeresis                          168     0xA8
copyright                          169     0xA9
ordfeminine                        170     0xAA
guillemotleft                      171     0xAB
notsign                            172     0xAC
\(Cs (currency)                       164     0xA4
\(Ye (yen)                            165     0xA5
\(bb (brokenbar)                      166     0xA6
\(sc (section)                        167     0xA7
\(ad (diaeresis)                      168     0xA8
\(co (copyright)                      169     0xA9
\(Of (ordfeminine)                    170     0xAA
\(Fo (guillemotleft)                  171     0xAB
\(no (notsign)                        172     0xAC
hyphen                             173     0xAD
registered                         174     0xAE
macron                             175     0xAF
degree                             176     0xB0
\(rg (registered)                     174     0xAE
\(a- (macron)                         175     0xAF
plusminus                          177     0xB1
twosuperior                        178     0xB2
threesuperior                      179     0xB3
acute                              180     0xB4
mu                                 181     0xB5
paragraph                          182     0xB6
\(de (degree)                         176     0xB0
\(+- (plusminus)                      177     0xB1
\(S2 (twosuperior)                    178     0xB2
\(S3 (threesuperior)                  179     0xB3
\(aa (acute)                          180     0xB4
periodcentered                     183     0xB7
cedilla                            184     0xB8
onesuperior                        185     0xB9
masculine                          186     0xBA
\(mc (mu)                             181     0xB5
\(ps (paragraph)                      182     0xB6
\(pc (periodcentered)                 183     0xB7
guillemotright                     187     0xBB
onequarter                         188     0xBC
\(ac (cedilla)                        184     0xB8
onehalf                            189     0xBD
threequarters                      190     0xBE
questiondown                       191     0xBF
Agrave                             192     0xC0
Aacute                             193     0xC1
Acircumflex                        194     0xC2
\(S1 (onesuperior)                    185     0xB9
\(Om (masculine)                      186     0xBA
\(Fc (guillemotright)                 187     0xBB
\(14 (onequarter)                     188     0xBC
\(12 (onehalf)                        189     0xBD
\(34 (threequarters)                  190     0xBE
\(r? (questiondown)                   191     0xBF
\(`A (Agrave)                         192     0xC0
\('A (Aacute)                         193     0xC1
\(^A (Acircumflex)                    194     0xC2
Atilde                             195     0xC3
Adiaeresis                         196     0xC4
Aring                              197     0xC5
AE                                 198     0xC6
Ccedilla                           199     0xC7
Egrave                             200     0xC8
\(~A (Atilde)                         195     0xC3
\(:A (Adiaeresis)                     196     0xC4
\(oA (Aring)                          197     0xC5
\(AE (AE)                             198     0xC6
\(,C (Ccedilla)                       199     0xC7
Eacute                             201     0xC9
Ecircumflex                        202     0xCA
Ediaeresis                         203     0xCB
Igrave                             204     0xCC
Iacute                             205     0xCD
Icircumflex                        206     0xCE
Idiaeresis                         207     0xCF
ETH                                208     0xD0
Ntilde                             209     0xD1
Ograve                             210     0xD2
Oacute                             211     0xD3
Ocircumflex                        212     0xD4
Otilde                             213     0xD5
Odiaeresis                         214     0xD6
multiply                           215     0xD7
\(`E (Egrave)                         200     0xC8
\('E (Eacute)                         201     0xC9
\(^E (Ecircumflex)                    202     0xCA
\(:E (Ediaeresis)                     203     0xCB
\(`I (Igrave)                         204     0xCC
\('I (Iacute)                         205     0xCD
\(^I (Icircumflex)                    206     0xCE
\(:I (Idiaeresis)                     207     0xCF
\(-D (ETH)                            208     0xD0
\(~N (Ntilde)                         209     0xD1
\(`O (Ograve)                         210     0xD2
\('O (Oacute)                         211     0xD3
\(^O (Ocircumflex)                    212     0xD4
\(~O (Otilde)                         213     0xD5
\(:O (Odiaeresis)                     214     0xD6
\(mu (multiply)                       215     0xD7
Oslash                             216     0xD8
Ugrave                             217     0xD9
\(/O (Oslash)                         216     0xD8
Uacute                             218     0xDA
Ucircumflex                        219     0xDB
Udiaeresis                         220     0xDC
Yacute                             221     0xDD
THORN                              222     0xDE
ssharp                             223     0xDF
agrave                             224     0xE0
\(`U (Ugrave)                         217     0xD9
\('U (Uacute)                         218     0xDA
\(^U (Ucircumflex)                    219     0xDB
\(:U (Udiaeresis)                     220     0xDC
\('Y (Yacute)                         221     0xDD
\(TP (THORN)                          222     0xDE
\(ss (ssharp)                         223     0xDF
aacute                             225     0xE1
acircumflex                        226     0xE2
atilde                             227     0xE3
adiaeresis                         228     0xE4
aring                              229     0xE5
ae                                 230     0xE6
ccedilla                           231     0xE7
egrave                             232     0xE8
\(`a (agrave)                         224     0xE0
\('a (aacute)                         225     0xE1
\(^a (acircumflex)                    226     0xE2
\(~a (atilde)                         227     0xE3
\(:a (adiaeresis)                     228     0xE4
\(oa (aring)                          229     0xE5
\(ae (ae)                             230     0xE6
\(,c (ccedilla)                       231     0xE7
eacute                             233     0xE9
ecircumflex                        234     0xEA
ediaeresis                         235     0xEB
igrave                             236     0xEC
iacute                             237     0xED
\(`e (egrave)                         232     0xE8
\('e (eacute)                         233     0xE9
\(^e (ecircumflex)                    234     0xEA
\(:e (ediaeresis)                     235     0xEB
\(`i (igrave)                         236     0xEC
\('i (iacute)                         237     0xED
icircumflex                        238     0xEE
idiaeresis                         239     0xEF
eth                                240     0xF0
ntilde                             241     0xF1
ograve                             242     0xF2
\(^i (icircumflex)                    238     0xEE
\(:i (idiaeresis)                     239     0xEF
\(Sd (eth)                            240     0xF0
\(~n (ntilde)                         241     0xF1
oacute                             243     0xF3
ocircumflex                        244     0xF4
otilde                             245     0xF5
odiaeresis                         246     0xF6
division                           247     0xF7
oslash                             248     0xF8
ugrave                             249     0xF9
uacute                             250     0xFA
ucircumflex                        251     0xFB
udiaeresis                         252     0xFC
yacute                             253     0xFD
thorn                              254     0xFE
ydiaeresis                         255     0xFF
\(`o (ograve)                         242     0xF2
\('o (oacute)                         243     0xF3
\(^o (ocircumflex)                    244     0xF4
\(~o (otilde)                         245     0xF5
\(:o (odiaeresis)                     246     0xF6
\(di (division)                       247     0xF7
\(/o (oslash)                         248     0xF8
\(`u (ugrave)                         249     0xF9
\('u (uacute)                         250     0xFA
\(^u (ucircumflex)                    251     0xFB
\(:u (udiaeresis)                     252     0xFC
\('y (yacute)                         253     0xFD
\(Tp (thorn)                          254     0xFE
\(:y (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
390
391
392
393
394
395
396


397
398
399
400
401
402
403
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405







+
+







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







-
-







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

547
548
549

550
551
552
553
554
555
556
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558







+



+







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
606
607
608
609
610
611
612


613
614
615
616
617
618
619
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623







+
+







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
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
633
634
635
636
637
638
639


640
641
642
643
644
645
646







-
-







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
812
813
814
815
816
817
818


819
820
821
822
823
824
825
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829







+
+







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
994
995
996
997
998
999
1000

1001
1002
1003
1004
1005
1006
1007
1008
1009
1010







-
+
+
+







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
\(eu (EuroSign)                      8364     0x20AC
.CE
.CS
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
1161
1162
1163
1164
1165
1166
1167


1168
1169
1170
1171
1172
1173
1174
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182







+
+







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
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
1219
1220
1221
1222
1223
1224
1225





1226
1227
1228
1229
1230
1231

1232
1233
1234
1235
1236
1237
1238
1239







-
-
-
-
-






-
+







Up                               65362     0xFF52
Right                            65363     0xFF53
Down                             65364     0xFF54
Prior                            65365     0xFF55
Next                             65366     0xFF56
End                              65367     0xFF57
Begin                            65368     0xFF58
Win_L                            65371     0xFF5B
Win_R                            65372     0xFF5C
.CE
.CS
App                              65373     0xFF5D
Select                           65376     0xFF60
Print                            65377     0xFF61
Execute                          65378     0xFF62
Insert                           65379     0xFF63
Undo                             65381     0xFF65
Redo                             65382     0xFF66
Menu                             65383     0xFF67
Menu (App)                       65383     0xFF67
Find                             65384     0xFF68
Cancel                           65385     0xFF69
Help                             65386     0xFF6A
Break                            65387     0xFF6B
Mode_switch                      65406     0xFF7E
Num_Lock                         65407     0xFF7F
KP_Space                         65408     0xFF80
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
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







-
-
+
+













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







Control_R                        65508     0xFFE4
Caps_Lock                        65509     0xFFE5
Shift_Lock                       65510     0xFFE6
Meta_L                           65511     0xFFE7
Meta_R                           65512     0xFFE8
Alt_L                            65513     0xFFE9
Alt_R                            65514     0xFFEA
Super_L                          65515     0xFFEB
Super_R                          65516     0xFFEC
Super_L (Win_L)                  65515     0xFFEB
Super_R (Win_R)                  65516     0xFFEC
Hyper_L                          65517     0xFFED
Hyper_R                          65518     0xFFEE
braille_dot_1                    65521     0xFFF1
braille_dot_2                    65522     0xFFF2
braille_dot_3                    65523     0xFFF3
braille_dot_4                    65524     0xFFF4
braille_dot_5                    65525     0xFFF5
braille_dot_6                    65526     0xFFF6
braille_dot_7                    65527     0xFFF7
braille_dot_8                    65528     0xFFF8
braille_dot_9                    65529     0xFFF9
braille_dot_10                   65530     0xFFFA
Delete                           65535     0xFFFF
Ibreve                        16777516     0x100012C
.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

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 arg ...\fR?
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for label widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
Returns the current value of the configuration option given

Changes to doc/labelframe.n.

91
92
93
94
95
96
97
98

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

112
113
114
115
116
117
118
91
92
93
94
95
96
97

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

111
112
113
114
115
116
117
118







-
+












-
+







.SH "WIDGET COMMAND"
.PP
The \fBlabelframe\fR command creates a new Tcl command whose
name is the same as the path name of the labelframe's window.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIPathName\fR is the name of the command, which is the same as
the labelframe widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for frame widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBlabelframe\fR
command.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? \fI?value option value ...\fR?
\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

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 arg ...\fR?
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for listbox widgets:
.TP
\fIpathName \fBactivate\fR \fIindex\fR
.
379
380
381
382
383
384
385
386


387
388
389
390
391
392
393
379
380
381
382
383
384
385

386
387
388
389
390
391
392
393
394







-
+
+







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.
\fINumber\fR must be an integer or a float, but if it is a float then
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR or an abbreviation
of one of these.
If \fIwhat\fR is \fBpages\fR then the view adjusts by
\fInumber\fR screenfuls.
If \fInumber\fR is negative then characters farther to the left
become visible;  if it is positive then characters farther to the right
become visible.
558
559
560
561
562
563
564
565

566
567
568
569
570
571
572
559
560
561
562
563
564
565

566
567
568
569
570
571
572
573







-
+







extend the selection to the active element just as if button 1
had been pressed with the Shift key down.
.IP [16]
In \fBextended\fR mode, the Escape key cancels the most recent
selection and restores all the elements in the selected range
to their previous selection state.
.IP [17]
Control-slash selects everything in the widget, except in
Control-/ selects everything in the widget, except in
\fBsingle\fR and \fBbrowse\fR modes, in which case it selects
the active element and deselects everything else.
.IP [18]
Control-backslash deselects everything in the widget, except in
\fBbrowse\fR mode where it has no effect.
.IP [19]
The F16 key (labelled Copy on many Sun workstations) or Meta-w

Changes to doc/loadTk.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14

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

14
15
16
17
18
19
20
21













-
+







'\"
'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH "Safe Tk" n 8.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
safe::loadTk \- Load Tk into a safe interpreter.
.SH SYNOPSIS
\fBsafe::loadTk \fIslave\fR ?\fB\-use\fR \fIwindowId\fR? ?\fB\-display\fR \fIdisplayName\fR?
\fBsafe::loadTk \fIchild\fR ?\fB\-use\fR \fIwindowId\fR? ?\fB\-display\fR \fIdisplayName\fR?
.BE
.SH DESCRIPTION
.PP
Safe Tk is based on Safe Tcl, which provides a mechanism that allows
restricted and mediated access to auto-loading and packages for safe
interpreters.  Safe Tk adds the ability to configure the interpreter for safe
Tk operations and load Tk into safe interpreters.
39
40
41
42
43
44
45
46

47
48
49
50
51
52



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


67
68
69
39
40
41
42
43
44
45

46
47
48
49



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


65
66
67
68
69







-
+



-
-
-
+
+
+












-
-
+
+



another display than the default one, specify it with \fB\-display\fR.  See
the \fBSECURITY ISSUES\fR section below for implementation details.
.SH "SECURITY ISSUES"
.PP
Please read the \fBsafe\fR manual page for Tcl to learn about the basic
security considerations for Safe Tcl.
.PP
\fBsafe::loadTk\fR adds the value of \fBtk_library\fR taken from the master
\fBsafe::loadTk\fR adds the value of \fBtk_library\fR taken from the parent
interpreter to the virtual access path of the safe interpreter so that
auto-loading will work in the safe interpreter.
.PP
Tk initialization is now safe with respect to not trusting the slave's state
for startup. \fBsafe::loadTk\fR registers the slave's name so when the Tk
initialization (\fBTk_SafeInit\fR) is called and in turn calls the master's
Tk initialization is now safe with respect to not trusting the child's state
for startup. \fBsafe::loadTk\fR registers the child's name so when the Tk
initialization (\fBTk_SafeInit\fR) is called and in turn calls the parent's
\fBsafe::InitTk\fR it will return the desired \fBargv\fR equivalent
(\fB\-use\fR \fIwindowId\fR, correct \fB\-display\fR, etc.)
.PP
When \fB\-use\fR is not used, the new toplevel created is specially decorated
so the user is always aware that the user interface presented comes from a
potentially unsafe code and can easily delete the corresponding interpreter.
.PP
On X11, conflicting \fB\-use\fR and \fB\-display\fR are likely to generate a
fatal X error.
.SH "SEE ALSO"
safe(n), interp(n), library(n), load(n), package(n), source(n), unknown(n)
.SH KEYWORDS
alias, auto-loading, auto_mkindex, load, master interpreter, safe
interpreter, slave interpreter, source
alias, auto-loading, auto_mkindex, load, parent interpreter, safe
interpreter, child interpreter, source
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/menu.n.

36
37
38
39
40
41
42
43

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

58
59
60
61
62
63
64
36
37
38
39
40
41
42

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

57
58
59
60
61
62
63
64







-
+













-
+







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

307
308
309
310
311
312
313
299
300
301
302
303
304
305

306
307
308
309
310
311
312
313







-
+







.SH "WIDGET COMMAND"
.PP
The \fBmenu\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
.PP
Many of the widget commands for a menu take as one argument an
indicator of which entry of the menu to operate on. These
indicators are called \fIindex\fRes and may be specified in
519
520
521
522
523
524
525
526
527


528
529
530
531
532
533
534
535
536
537

538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554

555

556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576

577
578
579
580
581
582
583
519
520
521
522
523
524
525


526
527
528
529
530
531
532
533
534
535
536

537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555

556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576

577
578
579
580
581
582
583
584







-
-
+
+









-
+

















+
-
+




















-
+







.SH "MENU ENTRY OPTIONS"
The following options are allowed on menu entries. Most options are not
supported by all entry types.
.TP
\fB\-activebackground \fIvalue\fR
.
Specifies a background color to use for displaying this entry when it
is active.
If this option is specified as an empty string (the default), then the
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.
.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.
.TP
\fB\-accelerator \fIvalue\fR
.
Specifies a string to display at the right side of the menu entry.
Normally describes an accelerator keystroke sequence that may be
used to invoke the same function as the menu entry. This is a display
option, it does not actually set the corresponding binding (which can
be achieved using the \fBbind\fR command). This option is not available
for separator or tear-off entries.
.TP
\fB\-background \fIvalue\fR
.
Specifies a background color to use for displaying this entry when it
is in the normal state (neither active nor disabled).
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.
.TP
\fB\-bitmap \fIvalue\fR
.
Specifies a bitmap to display in the menu instead of a textual
label, in any of the forms accepted by \fBTk_GetBitmap\fR.
This option overrides the \fB\-label\fR option
(as controlled by the \fB\-compound\fR option)
but may be reset
to an empty string to enable a textual label to be displayed.
If a \fB\-image\fR option has been specified, it overrides
\fB\-bitmap\fR.
This option is not available for separator or tear-off entries.
.TP
\fB\-columnbreak \fIvalue\fR
.
When this option is zero, the entry appears below the previous entry. When
this option is one, the entry appears at the top of a new column in the
menu.
This option is ignored on Aqua/Mac OS X, where menus are always a single
This option is ignored on Aqua/macOS, where menus are always a single
column.
.TP
\fB\-command \fIvalue\fR
.
Specifies a Tcl command to execute when the menu entry is invoked.
Not available for separator or tear-off entries.
.TP
599
600
601
602
603
604
605

606

607
608
609
610
611
612
613
600
601
602
603
604
605
606
607

608
609
610
611
612
613
614
615







+
-
+







the \fB\-font\fR option for the overall menu is used.
This option is not available for separator or tear-off entries.
.TP
\fB\-foreground \fIvalue\fR
.
Specifies a foreground color to use for displaying this entry when it
is in the normal state (neither active nor disabled).
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.
.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.,

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 arg ... \fR
\fBtk_bindForTraversal \fIarg ... \fR
.BE
.SH DESCRIPTION
.PP
These procedures were used in Tk 3.6 and earlier releases to help
manage pulldown menus and to implement keyboard traversal of menus.
In Tk 4.0 and later releases they are no
longer needed.  Stubs for these procedures have been retained for

Changes to doc/menubutton.n.

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







-
+







.SH "WIDGET COMMAND"
.PP
The \fBmenubutton\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for menubutton widgets:
.TP
\fIpathName \fBcget \fIoption\fR
.

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 arg ...\fR?
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for message widgets:
.TP
\fIpathName \fBcget \fIoption\fR
.

Changes to doc/options.n.

226
227
228
229
230
231
232
233

234
235
236
237
238
239
240
241
226
227
228
229
230
231
232

233

234
235
236
237
238
239
240







-
+
-







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. If this option is the empty string, the default color gray70
displayed. The default color is platform-specific.
is used.
.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.

18
19
20
21
22
23
24
25

26
27
28
29
30
31
32


33
34

35
36
37
38
39
40
41
42
43


44
45
46
47

48
49
50
51
52
53
54


55
56
57
58


59
60
61
62
63
64
65


66
67
68
69
70

71
72
73
74

75
76
77
78

79
80
81
82

83
84
85
86
87



88
89
90
91

92
93
94
95
96
97

98
99
100
101
102

103
104
105
106
107
108

109
110
111
112
113

114
115
116
117
118

119
120
121

122
123

124
125
126
127
128
129
130
131




132
133
134
135
136



137
138

139
140
141

142
143

144
145
146
147


148
149

150
151

152
153
154

155
156
157
158

159
160
161
162
163



164
165





166
167
168
169


170
171

172
173

174
175
176

177
178
179
180
181




182
183

184
185
186


187
188
189

190
191
192

193
194
195
196
197


198
199

200
201
202

203
204
205

206
207
208
209
210



211
212
213

214
215

216
217
218
219



220
221

222
223

224
225

226
227
228
229
230



231
232
233

234
235

236
237
238
239
240



241
242
243
244
245

246
247
248

249
250

251
252
253


254
255
256


257
258
259
260
261
262
263
264






265
266
267

268
269
270
271
272
273
274
18
19
20
21
22
23
24

25
26
27
28
29
30


31
32
33

34
35
36
37
38
39
40
41


42
43
44
45
46

47
48
49
50
51
52


53
54
55
56


57
58
59
60
61
62
63


64
65
66
67
68
69

70
71
72
73

74
75
76
77

78
79
80
81

82
83
84



85
86
87
88
89
90

91
92
93
94
95
96

97
98
99
100
101

102
103
104
105
106
107

108
109
110
111
112

113
114
115
116
117

118
119
120

121
122

123
124
125
126
127




128
129
130
131
132
133



134
135
136
137

138
139
140

141
142

143
144
145


146
147
148

149
150

151
152
153

154
155
156
157

158
159
160



161
162
163
164

165
166
167
168
169
170
171


172
173
174

175
176

177
178
179

180
181




182
183
184
185
186

187
188


189
190
191
192

193
194
195

196
197
198
199


200
201
202

203
204
205

206
207
208

209
210
211



212
213
214
215
216

217
218

219
220



221
222
223
224

225
226

227
228

229
230
231



232
233
234
235
236

237
238

239
240
241



242
243
244
245
246
247
248

249
250
251

252
253

254
255


256
257
258


259
260
261
262






263
264
265
266
267
268
269
270

271
272
273
274
275
276
277
278







-
+





-
-
+
+

-
+







-
-
+
+



-
+





-
-
+
+


-
-
+
+





-
-
+
+




-
+



-
+



-
+



-
+


-
-
-
+
+
+



-
+





-
+




-
+





-
+




-
+




-
+


-
+

-
+




-
-
-
-
+
+
+
+


-
-
-
+
+
+

-
+


-
+

-
+


-
-
+
+

-
+

-
+


-
+



-
+


-
-
-
+
+
+

-
+
+
+
+
+


-
-
+
+

-
+

-
+


-
+

-
-
-
-
+
+
+
+

-
+

-
-
+
+


-
+


-
+



-
-
+
+

-
+


-
+


-
+


-
-
-
+
+
+


-
+

-
+

-
-
-
+
+
+

-
+

-
+

-
+


-
-
-
+
+
+


-
+

-
+


-
-
-
+
+
+




-
+


-
+

-
+

-
-
+
+

-
-
+
+


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


-
+







.PP
The \fBpack\fR command is used to communicate with the packer,
a geometry manager that arranges the children of a parent by
packing them in order around the edges of the parent.
The \fBpack\fR command can have any of several forms, depending
on the \fIoption\fR argument:
.TP
\fBpack \fIslave \fR?\fIslave ...\fR? ?\fIoptions\fR?
\fBpack \fIwindow \fR?\fIwindow ...\fR? ?\fIoptions\fR?
If the first argument to \fBpack\fR is a window name (any value
starting with
.QW . ),
then the command is processed in the same way as \fBpack configure\fR.
.TP
\fBpack configure \fIslave \fR?\fIslave ...\fR? ?\fIoptions\fR?
The arguments consist of the names of one or more slave windows
\fBpack configure \fIwindow \fR?\fIwindow ...\fR? ?\fIoptions\fR?
The arguments consist of the names of one or more content windows
followed by pairs of arguments that specify how
to manage the slaves.
to manage the content.
See \fBTHE PACKER ALGORITHM\fR below for details on how the options
are used by the packer.
The following options are supported:
.RS
.TP
\fB\-after \fIother\fR
\fIOther\fR must the name of another window.
Use its master as the master for the slaves, and insert
the slaves just after \fIother\fR in the packing order.
Use its container as the container for the content, and insert
the content just after \fIother\fR in the packing order.
.TP
\fB\-anchor \fIanchor\fR
\fIAnchor\fR must be a valid anchor position such as \fBn\fR
or \fBsw\fR; it specifies where to position each slave in its
or \fBsw\fR; it specifies where to position each content in its
parcel.
Defaults to \fBcenter\fR.
.TP
\fB\-before \fIother\fR
\fIOther\fR must the name of another window.
Use its master as the master for the slaves, and insert
the slaves just before \fIother\fR in the packing order.
Use its container as the container for the content, and insert
the content just before \fIother\fR in the packing order.
.TP
\fB\-expand \fIboolean\fR
Specifies whether the slaves should be expanded to consume
extra space in their master.
Specifies whether the content should be expanded to consume
extra space in their container.
\fIBoolean\fR may have any proper boolean value, such as \fB1\fR
or \fBno\fR.
Defaults to 0.
.TP
\fB\-fill \fIstyle\fR
If a slave's parcel is larger than its requested dimensions, this
option may be used to stretch the slave.
If a content's parcel is larger than its requested dimensions, this
option may be used to stretch the content.
\fIStyle\fR must have one of the following values:
.RS
.TP
\fBnone\fR
Give the slave its requested dimensions plus any internal padding
Give the content its requested dimensions plus any internal padding
requested with \fB\-ipadx\fR or \fB\-ipady\fR.  This is the default.
.TP
\fBx\fR
Stretch the slave horizontally to fill the entire width of its
Stretch the content horizontally to fill the entire width of its
parcel (except leave external padding as specified by \fB\-padx\fR).
.TP
\fBy\fR
Stretch the slave vertically to fill the entire height of its
Stretch the content vertically to fill the entire height of its
parcel (except leave external padding as specified by \fB\-pady\fR).
.TP
\fBboth\fR
Stretch the slave both horizontally and vertically.
Stretch the content both horizontally and vertically.
.RE
.TP
\fB\-in \fIother\fR
Insert the slave(s) at the end of the packing order for the master
window given by \fIother\fR.
\fB\-in \fIcontainer\fR
Insert the window at the end of the packing order for the container
window given by \fIcontainer\fR.
.TP
\fB\-ipadx \fIamount\fR
\fIAmount\fR specifies how much horizontal internal padding to
leave on each side of the slave(s).
leave on each side of the content.
\fIAmount\fR must be a valid screen distance, such as \fB2\fR or \fB.5c\fR.
It defaults to 0.
.TP
\fB\-ipady \fIamount\fR
\fIAmount\fR specifies how much vertical internal padding to
leave on each side of the slave(s).
leave on each side of the content.
\fIAmount\fR  defaults to 0.
.TP
\fB\-padx \fIamount\fR
\fIAmount\fR specifies how much horizontal external padding to
leave on each side of the slave(s).  \fIAmount\fR may be a list
leave on each side of the content.  \fIAmount\fR may be a list
of two values to specify padding for left and right separately.
\fIAmount\fR defaults to 0.
.TP
\fB\-pady \fIamount\fR
\fIAmount\fR specifies how much vertical external padding to
leave on each side of the slave(s).  \fIAmount\fR may be a list
leave on each side of the content.  \fIAmount\fR may be a list
of two values to specify padding for top and bottom separately.
\fIAmount\fR defaults to 0.
.TP
\fB\-side \fIside\fR
Specifies which side of the master the slave(s) will be packed against.
Specifies which side of the container the content will be packed against.
Must be \fBleft\fR, \fBright\fR, \fBtop\fR, or \fBbottom\fR.
Defaults to \fBtop\fR.
.LP
If no \fB\-in\fR, \fB\-after\fR or \fB\-before\fR option is specified
then each of the slaves will be inserted at the end of the packing list
then each of the content will be inserted at the end of the packing list
for its parent unless it is already managed by the packer (in which
case it will be left where it is).
If one of these options is specified then all the slaves will be
If one of these options is specified then all the content will be
inserted at the specified point.
If any of the slaves are already managed by the geometry manager
If any of the content are already managed by the geometry manager
then any unspecified options for them retain their previous values rather
than receiving default values.
.RE
.TP
\fBpack forget \fIslave \fR?\fIslave ...\fR?
Removes each of the \fIslave\fRs from the packing order for its
master and unmaps their windows.
The slaves will no longer be managed by the packer.
\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 TIP518
If the last slave of the master becomes unmanaged, this will also send
the virtual event \fB<<NoManagedChild>>\fR to the master; the master
.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 TIP518
.VE "TIP 518"
.RE
.TP
\fBpack info \fIslave\fR
\fBpack info \fIwindow\fR
Returns a list whose elements are the current configuration state of
the slave given by \fIslave\fR in the same option-value form that
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 \fImaster\fR"
where \fImaster\fR is the slave's master.
.QW "\fB\-in \fIcontainer\fR"
where \fIcontainer\fR is the window's container.
.TP
\fBpack propagate \fImaster\fR ?\fIboolean\fR?
\fBpack propagate \fIcontainer\fR ?\fIboolean\fR?
If \fIboolean\fR has a true boolean value such as \fB1\fR or \fBon\fR
then propagation is enabled for \fImaster\fR, which must be a window
then propagation is enabled for \fIcontainer\fR, which must be a window
name (see \fBGEOMETRY PROPAGATION\fR below).
If \fIboolean\fR has a false boolean value then propagation is
disabled for \fImaster\fR.
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 \fImaster\fR.
for \fIcontainer\fR.
Propagation is enabled by default.
.TP
\fBpack slaves \fImaster\fR
Returns a list of all of the slaves in the packing order for \fImaster\fR.
The order of the slaves in the list is the same as their order in
\fBpack content \fIwindow\fR
Returns a list of all of the content windows in the packing order for \fIwindow\fR.
The order of the content windows in the list is the same as their order in
the packing order.
If \fImaster\fR has no slaves then an empty string is returned.
If \fIwindow\fR has no content then an empty string is returned.
.TP
\fBpack slaves \fIwindow\fR
.
Synonym for . \fBpack content \fIwindow\fR
.SH "THE PACKER ALGORITHM"
.PP
For each master the packer maintains an ordered list of slaves
called the \fIpacking list\fR.
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 master for each slave and the slave's
options are used to specify the container for each content and the content's
position in the packing list.
If none of these options is given for a slave then the slave
If none of these options is given for a content then the content
is added to the end of the packing list for its parent.
.PP
The packer arranges the slaves for a master by scanning the
The packer arranges the content windows for a container by scanning the
packing list in order.
At the time it processes each slave, a rectangular area within
the master is still unallocated.
This area is called the \fIcavity\fR;  for the first slave it
is the entire area of the master.
At the time it processes each content, a rectangular area within
the container is still unallocated.
This area is called the \fIcavity\fR;  for the first content it
is the entire area of the container.
.PP
For each slave the packer carries out the following steps:
For each content the packer carries out the following steps:
.IP [1]
The packer allocates a rectangular \fIparcel\fR for the slave
along the side of the cavity given by the slave's \fB\-side\fR option.
The packer allocates a rectangular \fIparcel\fR for the content
along the side of the cavity given by the content's \fB\-side\fR option.
If the side is top or bottom then the width of the parcel is
the width of the cavity and its height is the requested height
of the slave plus the \fB\-ipady\fR and \fB\-pady\fR options.
of the content plus the \fB\-ipady\fR and \fB\-pady\fR options.
For the left or right side the height of the parcel is
the height of the cavity and the width is the requested width
of the slave plus the \fB\-ipadx\fR and \fB\-padx\fR options.
of the content plus the \fB\-ipadx\fR and \fB\-padx\fR options.
The parcel may be enlarged further because of the \fB\-expand\fR
option (see \fBEXPANSION\fR below)
.IP [2]
The packer chooses the dimensions of the slave.
The width will normally be the slave's requested width plus
The packer chooses the dimensions of the content.
The width will normally be the content's requested width plus
twice its \fB\-ipadx\fR option and the height will normally be
the slave's requested height plus twice its \fB\-ipady\fR
the content's requested height plus twice its \fB\-ipady\fR
option.
However, if the \fB\-fill\fR option is \fBx\fR or \fBboth\fR
then the width of the slave is expanded to fill the width of the parcel,
then the width of the content is expanded to fill the width of the parcel,
minus twice the \fB\-padx\fR option.
If the \fB\-fill\fR option is \fBy\fR or \fBboth\fR
then the height of the slave is expanded to fill the width of the parcel,
then the height of the content is expanded to fill the width of the parcel,
minus twice the \fB\-pady\fR option.
.IP [3]
The packer positions the slave over its parcel.
If the slave is smaller than the parcel then the \fB\-anchor\fR
option determines where in the parcel the slave will be placed.
The packer positions the content over its parcel.
If the content is smaller than the parcel then the \fB\-anchor\fR
option determines where in the parcel the content will be placed.
If \fB\-padx\fR or \fB\-pady\fR is non-zero, then the given
amount of external padding will always be left between the
slave and the edges of the parcel.
content and the edges of the parcel.
.PP
Once a given slave has been packed, the area of its parcel
Once a given content has been packed, the area of its parcel
is subtracted from the cavity, leaving a smaller rectangular
cavity for the next slave.
If a slave does not use all of its parcel, the unused space
in the parcel will not be used by subsequent slaves.
cavity for the next content.
If a content does not use all of its parcel, the unused space
in the parcel will not be used by subsequent content.
If the cavity should become too small to meet the needs of
a slave then the slave will be given whatever space is
a content then the content will be given whatever space is
left in the cavity.
If the cavity shrinks to zero size, then all remaining slaves
If the cavity shrinks to zero size, then all remaining content
on the packing list will be unmapped from the screen until
the master window becomes large enough to hold them again.
the container window becomes large enough to hold them again.
.SS "EXPANSION"
.PP
If a master window is so large that there will be extra space
left over after all of its slaves have been packed, then the
extra space is distributed uniformly among all of the slaves
If a container window is so large that there will be extra space
left over after all of its content have been packed, then the
extra space is distributed uniformly among all of the content
for which the \fB\-expand\fR option is set.
Extra horizontal space is distributed among the expandable
slaves whose \fB\-side\fR is \fBleft\fR or \fBright\fR,
content whose \fB\-side\fR is \fBleft\fR or \fBright\fR,
and extra vertical space is distributed among the expandable
slaves whose \fB\-side\fR is \fBtop\fR or \fBbottom\fR.
content whose \fB\-side\fR is \fBtop\fR or \fBbottom\fR.
.SS "GEOMETRY PROPAGATION"
.PP
The packer normally computes how large a master must be to
just exactly meet the needs of its slaves, and it sets the
requested width and height of the master to these dimensions.
The packer normally computes how large a container must be to
just exactly meet the needs of its content, and it sets the
requested width and height of the container to these dimensions.
This causes geometry information to propagate up through a
window hierarchy to a top-level window so that the entire
sub-tree sizes itself to fit the needs of the leaf windows.
However, the \fBpack propagate\fR command may be used to
turn off propagation for one or more masters.
turn off propagation for one or more containers.
If propagation is disabled then the packer will not set
the requested width and height of the packer.
This may be useful if, for example, you wish for a master
This may be useful if, for example, you wish for a container
window to have a fixed size that you specify.
.SH "RESTRICTIONS ON MASTER WINDOWS"
.SH "RESTRICTIONS ON CONTAINER WINDOWS"
.PP
The master for each slave must either be the slave's parent
(the default) or a descendant of the slave's parent.
The container for each content must either be the content's parent
(the default) or a descendant of the content's parent.
This restriction is necessary to guarantee that the
slave can be placed over any part of its master that is
visible without danger of the slave being clipped by its parent.
content can be placed over any part of its container that is
visible without danger of the content being clipped by its parent.
.SH "PACKING ORDER"
.PP
If the master for a slave is not its parent then you must make sure
that the slave is higher in the stacking order than the master.
Otherwise the master will obscure the slave and it will appear as
if the slave has not been packed correctly.
The easiest way to make sure the slave is higher than the master is
to create the master window first:  the most recently created window
If the container for a content is not its parent then you must make sure
that the content is higher in the stacking order than the container.
Otherwise the container will obscure the content and it will appear as
if the content has not been packed correctly.
The easiest way to make sure the content is higher than the container is
to create the container window first:  the most recently created window
will be highest in the stacking order.
Or, you can use the \fBraise\fR and \fBlower\fR commands to change
the stacking order of either the master or the slave.
the stacking order of either the container or the content.
.SH EXAMPLE
.PP
.CS
# Make the widgets
label .t \-text "This widget is at the top"    \-bg red
label .b \-text "This widget is at the bottom" \-bg green
label .l \-text "Left\enHand\enSide"

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 arg ...\fR?
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIPathName\fR is the name of the command, which is the same as
the panedwindow widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for panedwindow widgets:
.TP
\fIpathName \fBadd \fIwindow \fR?\fIwindow ...\fR? ?\fIoption value ...\fR?
326
327
328
329
330
331
332
333

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

333
334
335
336
337
338
339
340







-
+







on each side of the sash, and thus the widgets in those panes, are
adjusted.
.PP
When a pane is resized from outside (e.g. it is packed to expand and
fill, and the containing toplevel is resized), space is added to the final
(rightmost or bottommost) pane in the window.
.PP
Unlike slave windows managed by e.g. pack or grid, the panes managed by a
Unlike child windows managed by e.g. pack or grid, the panes managed by a
panedwindow do not change width or height to accommodate changes in the
requested widths or heights of the panes, once these have become mapped.
Therefore it may be advisable, particularly when creating layouts
interactively, to not add a pane to the panedwindow widget until after the
geometry requests of that pane has been finalized (i.e., all components of
the pane inserted, all options affecting geometry set to their proper
values, etc.).

Changes to doc/photo.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







-
+







\fIimageName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
\fIimageName \fBcopy \fIsourceImage\fR ?\fIoption value(s) ...\fR?
\fIimageName \fBdata\fR ?\fIoption value(s) ...\fR?
\fIimageName \fBget \fIx y\fR ?\fIoption\fR?
\fIimageName \fBput \fIdata\fR ?\fIoption value(s) ...\fR?
\fIimageName \fBread \fIfilename\fR ?\fIoption value(s) ...\fR?
\fIimageName \fBredither\fR
\fIimageName \fBtransparency \fIsubcommand \fR?\fIarg arg ...\fR?
\fIimageName \fBtransparency \fIsubcommand \fR?\fIarg ...\fR?
\fIimageName \fBwrite \fIfilename\fR ?\fIoption value(s) ...\fR?
.fi
.BE
.SH DESCRIPTION
.PP
A photo is an image whose pixels can display any color with a varying
degree of transparency (the alpha channel). A photo image is stored
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
113
114
115
116
117
118
119
120







+
+
+
+
+
+
+
+
+
+







.TP
\fB\-height \fInumber\fR
.
Specifies the height of the image, in pixels.  This option is useful
primarily in situations where the user wishes to build up the contents
of the image piece by piece.  A value of zero (the default) allows the
image to expand or shrink vertically to fit the data stored in it.
.VS 8.7
.TP
\fB\-metadata \fImetadata\fR
.
Set the metadata dictionary of the image.
Additional keys may be set within the metadata dictionary of the image,
if image data is processed due to a \fB\-file\fR or \fB\-data\fR options
and the driver outputs any metadata keys.
See section \fBMETADATA DICTIONARY\fR below.
.VE 8.7
.TP
\fB\-palette \fIpalette-spec\fR
.
Specifies the resolution of the color cube to be allocated for
displaying this image, and thus the number of colors used from the
colormaps of the windows where it is displayed.  The
\fIpalette-spec\fR string may be either a single decimal number,
124
125
126
127
128
129
130
131

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

150
151
152
153
154
155
156
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

159
160
161
162
163
164
165
166







-
+

















-
+







.PP
When a photo image is created, Tk also creates a new command
whose name is the same as the image.
This command may be used to invoke various operations
on the image.
It has the following general form:
.CS
\fIimageName option \fR?\fIarg arg ...\fR?
\fIimageName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
.PP
Those options that write data to the image generally expand the size
of the image, if necessary, to accommodate the data written to the
image, unless the user has specified non-zero values for the
\fB\-width\fR and/or \fB\-height\fR configuration options, in which
case the width and/or height, respectively, of the image will not be
changed.
.PP
The following commands are possible for photo images:
.TP
\fIimageName \fBblank\fR
.
Blank the image; that is, set the entire image to have no data, so it
will be displayed as transparent, and the background of whatever
window it is displayed in will show through.
window it is displayed in will show through. The metadata dict of the image is not changed.
.TP
\fIimageName \fBcget\fR \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the
\fBimage create\fR \fBphoto\fR command.
165
166
167
168
169
170
171




172
173
174
175
176
177
178
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192







+
+
+
+







one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the
\fBimage create\fR \fBphoto\fR command.
.VS 8.7
Note: setting the \fB\-metadata\fR option without any other option
will not invoke the image format driver to recreate the bitmap.
.VE 8.7
.TP
\fIimageName \fBcopy\fR \fIsourceImage\fR ?\fIoption value(s) ...\fR?
.
Copies a region from the image called \fIsourceImage\fR (which must
be a photo image) to the image called \fIimageName\fR, possibly with
pixel zooming and/or subsampling.  If no options are specified, this
command copies the whole of \fIsourceImage\fR into \fIimageName\fR,
283
284
285
286
287
288
289
290
291
292










293
294
295
296
297
298
299
297
298
299
300
301
302
303

304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322







-


+
+
+
+
+
+
+
+
+
+







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
\fB\-metadata\fR \fImetadata\fR
.
Image format handler may use metadata to be included in the returned
data string.
The specified \fImetadata\fR is passed to the driver for inclusion in the
data.
If no \fB\-metadata\fR option is given, the current metadata of the
image is used.
.VE 8.7
.RE
\fIimageName \fBget\fR \fIx y\fR ?\fB-withalpha\fR?
.
Returns the color of the pixel at coordinates (\fIx\fR,\fIy\fR) in the
image as a list of three integers between 0 and 255, representing the
red, green and blue components respectively. If the \fB-withalpha\fR
option is specified, the returned list will have a fourth element
representing the alpha value of the pixel as an integer between 0 and
318
319
320
321
322
323
324









325
326
327
328
329
330
331
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363







+
+
+
+
+
+
+
+
+







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.
.VS 8.7
.TP
\fB\-metadata\fR \fImetadata\fR
.
A specified \fImetadata\fR is passed to the image format driver when interpreting
the data.
Note: The current metadata of the image is not passed to the format driver
and is not changed by the command.
.VE 8.7
.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
363
364
365
366
367
368
369









370
371
372
373
374
375
376
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417







+
+
+
+
+
+
+
+
+







Specifies a rectangular sub-region of the image file data to be copied
to the destination image.  If only \fIx1\fR and \fIy1\fR are
specified, the region extends from (\fIx1,y1\fR) to the bottom-right
corner of the image in the image file.  If all four coordinates are
specified, they specify diagonally opposite corners or the region.
The default, if this option is not specified, is the whole of the
image in the image file.
.VS 8.7
.TP
\fB\-metadata\fR \fImetadata\fR
.
A specified \fImetadata\fR is passed to the image format driver when interpreting
the data.
Note: The current metadata of the image is not passed to the format driver
and is not changed by the command.
.VE 8.7
.TP
\fB\-shrink\fR
.
If this option, the size of \fIimageName\fR will be reduced, if
necessary, so that the region into which the image file data are read
is at the bottom-right corner of the \fIimageName\fR.  This option
will not affect the width or height of the image if the user has
390
391
392
393
394
395
396
397

398
399
400
401
402
403
404
431
432
433
434
435
436
437

438
439
440
441
442
443
444
445







-
+







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 arg ...\fR?
\fIimageName \fBtransparency \fIsubcommand \fR?\fIarg ...\fR?
.
Allows examination and manipulation of the transparency information in
the photo image.  Several subcommands are available:
.RS
.VS 8.7
.TP
\fIimageName \fBtransparency get \fIx y\fR ?\fB-alpha\fR?
456
457
458
459
460
461
462










463
464
465
466
467
468
469
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520







+
+
+
+
+
+
+
+
+
+







diagonally opposite corners of the rectangular region.  The default,
if this option is not given, is the whole image.
.TP
\fB\-grayscale\fR
.
If this options is specified, the data will not contain color
information. All pixel data will be transformed into grayscale.
.VS 8.7
.TP
\fB\-metadata\fR \fBmetadata\fR
.
Image format handler may use metadata to be included in the written file.
The specified \fImetadata\fR is passed to the driver for inclusion in the
file.
If no \fB\-metadata\fR option is given, the current metadata of the
image is used.
.VE 8.7
.RE
.SH "IMAGE FORMATS"
.PP
The photo image code is structured to allow handlers for additional
image file formats to be added easily.  The photo image code maintains
a list of these handlers.  Handlers are added to the list by
registering them with a call to \fBTk_CreatePhotoImageFormat\fR.  The
678
679
680
681
682
683
684

































685
686
687
688
689
690
691
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775







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







The user can exercise some control over the number of colors that a
photo image uses with the \fB\-palette\fR configuration option.  If
this option is used, it specifies the maximum number of shades of
each primary color to try to allocate.  It can also be used to force
the image to be displayed in shades of gray, even on a color display,
by giving a single number rather than three numbers separated by
slashes.
.VS 8.7
.SH "METADATA DICTIONARY"
.PP
Each image has a metadata dictionary property.
This dictionary is not relevant to the bitmap representation of the
image, but may contain additional information like resolution or
comments.
Image format drivers may output metadata when image data is
parsed, or may use metadata to be included in image files or formats.
.SS "METADATA KEYS"
.PP
Each image format driver supports an individual set of metadata dictionary
keys. Predefined keys are:
.TP
DPI
.
Horizontal image resolution in DPI as a double value.
Supported by format \fBpng\fR.
.TP
aspect
.
Aspect ratio horizontal divided by vertical as double value.
Supported by formats \fBgif\fR and \fBpng\fR.
.TP
comment
.
Image text comment.
Supported by formats \fBgif\fR and \fBpng\fR.
.PP
It is valid to set any key in the metadata dict.
A format driver will ignore keys it does not handle.
.PP
.VE 8.7
.SH CREDITS
.PP
The photo image type was designed and implemented by Paul Mackerras,
based on his earlier photo widget and some suggestions from
John Ousterhout.
.SH EXAMPLE
.PP

Changes to doc/place.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
38
39
40

41
42
43
44
45
46
47
14
15
16
17
18
19
20


21
22
23



24
25
26
27


28
29
30
31
32

33
34
35
36
37
38
39

40
41
42
43
44
45
46
47







-
-
+
+

-
-
-
+
+
+

-
-
+
+



-
+






-
+







.SH SYNOPSIS
\fBplace \fIoption arg \fR?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
The placer is a geometry manager for Tk.
It provides simple fixed placement of windows, where you specify
the exact size and location of one window, called the \fIslave\fR,
within another window, called the \fImaster\fR.
the exact size and location of one window, called the \fIcontent\fR,
within another window, called the \fIcontainer\fR.
The placer also provides rubber-sheet placement, where you specify the
size and location of the slave in terms of the dimensions of
the master, so that the slave changes size and location
in response to changes in the size of the master.
size and location of the content in terms of the dimensions of
the container, so that the content changes size and location
in response to changes in the size of the container.
Lastly, the placer allows you to mix these styles of placement so
that, for example, the slave has a fixed width and height but is
centered inside the master.
that, for example, the content has a fixed width and height but is
centered inside the container.
.PP
.TP
\fBplace \fIwindow option value \fR?\fIoption value ...\fR?
Arrange for the placer to manage the geometry of a slave whose
Arrange for the placer to manage the geometry of a content whose
pathName is \fIwindow\fR.  The remaining arguments consist of one or
more \fIoption\-value\fR pairs that specify the way in which
\fIwindow\fR's geometry is managed.  \fIOption\fR may have any of the
values accepted by the \fBplace configure\fR command.
.TP
\fBplace configure \fIwindow \fR?\fIoption\fR? ?\fIvalue option value ...\fR?
Query or modify the geometry options of the slave given by
Query or modify the geometry options of the content given by
\fIwindow\fR.  If no \fIoption\fR is specified, this command returns a
list describing the available options (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
55
56
57
58
59
60
61
62

63
64
65
66
67

68
69
70


71
72
73

74
75
76
77
78

79
80

81
82

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


99
100

101
102

103
104
105
106


107
108
109
110
111
112
113
114
115




116
117

118
119
120
121
122
123
124
125




126
127

128
129
130

131
132
133
134

135
136

137
138
139


140
141
142

143
144
145
146

147
148

149
150
151


152
153
154
155
156
157
158
159
160
161
162
163

164
165
166
167

168
169
170

171
172
173
174

175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196







197
198
199
200
201
202
203
204
205
206


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

225
226
227
228
229
230
231
232

233
234
235
236
237

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

253
254
255
55
56
57
58
59
60
61

62
63
64
65
66

67
68


69
70
71
72

73
74
75
76
77

78
79

80
81

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


97
98
99

100
101

102
103
104


105
106
107
108
109
110
111




112
113
114
115
116

117
118
119
120
121




122
123
124
125
126

127
128
129

130
131
132
133

134
135

136
137


138
139
140
141

142
143
144
145

146
147

148
149


150
151
152
153
154
155
156
157
158
159
160
161
162

163
164
165
166

167
168
169

170
171
172
173

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193



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


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

228
229
230
231
232
233
234
235

236
237
238
239
240

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

256
257
258
259







-
+




-
+

-
-
+
+


-
+




-
+

-
+

-
+














-
-
+
+

-
+

-
+


-
-
+
+





-
-
-
-
+
+
+
+

-
+




-
-
-
-
+
+
+
+

-
+


-
+



-
+

-
+

-
-
+
+


-
+



-
+

-
+

-
-
+
+











-
+



-
+


-
+



-
+



















-
-
-
+
+
+
+
+
+
+








-
-
+
+

















-
+







-
+




-
+














-
+



\fIWhere\fR specifies which point of \fIwindow\fR is to be positioned
at the (x,y) location selected by the \fB\-x\fR, \fB\-y\fR,
\fB\-relx\fR, and \fB\-rely\fR options.
The anchor point is in terms of the outer area of \fIwindow\fR
including its border, if any.
Thus if \fIwhere\fR is \fBse\fR then the lower-right corner of
\fIwindow\fR's border will appear at the given (x,y) location
in the master.
in the container.
The anchor position defaults to \fBnw\fR.
.TP
\fB\-bordermode \fImode\fR
\fIMode\fR determines the degree to which borders within the
master are used in determining the placement of the slave.
container are used in determining the placement of the content.
The default and most common value is \fBinside\fR.
In this case the placer considers the area of the master to
be the innermost area of the master, inside any border:
In this case the placer considers the area of the container to
be the innermost area of the container, inside any border:
an option of \fB\-x 0\fR corresponds to an x-coordinate just
inside the border and an option of \fB\-relwidth 1.0\fR
means \fIwindow\fR will fill the area inside the master's
means \fIwindow\fR will fill the area inside the container's
border.
.RS
.PP
If \fImode\fR is \fBoutside\fR then the placer considers
the area of the master to include its border;
the area of the container to include its border;
this mode is typically used when placing \fIwindow\fR
outside its master, as with the options \fB\-x 0 \-y 0 \-anchor ne\fR.
outside its container, as with the options \fB\-x 0 \-y 0 \-anchor ne\fR.
Lastly, \fImode\fR may be specified as \fBignore\fR, in which
case borders are ignored:  the area of the master is considered
case borders are ignored:  the area of the container is considered
to be its official X area, which includes any internal border but
no external border.  A bordermode of \fBignore\fR is probably
not very useful.
.RE
.TP
\fB\-height \fIsize\fR
\fISize\fR specifies the height for \fIwindow\fR in screen units
(i.e. any of the forms accepted by \fBTk_GetPixels\fR).
The height will be the outer dimension of \fIwindow\fR including its
border, if any.
If \fIsize\fR is an empty string, or if no \fB\-height\fR or
\fB\-relheight\fR option is specified, then the height requested
internally by the window will be used.
.TP
\fB\-in \fImaster\fR
\fIMaster\fR specifies the path name of the window relative
\fB\-in \fIcontainer\fR
\fIContainer\fR specifies the path name of the window relative
to which \fIwindow\fR is to be placed.
\fIMaster\fR must either be \fIwindow\fR's parent or a descendant
\fIContainer\fR must either be \fIwindow\fR's parent or a descendant
of \fIwindow\fR's parent.
In addition, \fImaster\fR and \fIwindow\fR must both be descendants
In addition, \fIcontainer\fR and \fIwindow\fR must both be descendants
of the same top-level window.
These restrictions are necessary to guarantee
that \fIwindow\fR is visible whenever \fImaster\fR is visible.
If this option is not specified then the master defaults to
that \fIwindow\fR is visible whenever \fIcontainer\fR is visible.
If this option is not specified then the other window defaults to
\fIwindow\fR's parent.
.TP
\fB\-relheight \fIsize\fR
\fISize\fR specifies the height for \fIwindow\fR.
In this case the height is specified as a floating-point number
relative to the height of the master: 0.5 means \fIwindow\fR will
be half as high as the master, 1.0 means \fIwindow\fR will have
the same height as the master, and so on.
If both \fB\-height\fR and \fB\-relheight\fR are specified for a slave,
relative to the height of the container: 0.5 means \fIwindow\fR will
be half as high as the container, 1.0 means \fIwindow\fR will have
the same height as the container, and so on.
If both \fB\-height\fR and \fB\-relheight\fR are specified for a content,
their values are summed.  For example, \fB\-relheight 1.0 \-height \-2\fR
makes the slave 2 pixels shorter than the master.
makes the content 2 pixels shorter than the container.
.TP
\fB\-relwidth \fIsize\fR
\fISize\fR specifies the width for \fIwindow\fR.
In this case the width is specified as a floating-point number
relative to the width of the master: 0.5 means \fIwindow\fR will
be half as wide as the master, 1.0 means \fIwindow\fR will have
the same width as the master, and so on.
If both \fB\-width\fR and \fB\-relwidth\fR are specified for a slave,
relative to the width of the container: 0.5 means \fIwindow\fR will
be half as wide as the container, 1.0 means \fIwindow\fR will have
the same width as the container, and so on.
If both \fB\-width\fR and \fB\-relwidth\fR are specified for a content,
their values are summed.  For example, \fB\-relwidth 1.0 \-width 5\fR
makes the slave 5 pixels wider than the master.
makes the content 5 pixels wider than the container.
.TP
\fB\-relx \fIlocation\fR
\fILocation\fR specifies the x-coordinate within the master window
\fILocation\fR specifies the x-coordinate within the container window
of the anchor point for \fIwindow\fR.
In this case the location is specified in a relative fashion
as a floating-point number:  0.0 corresponds to the left edge
of the master and 1.0 corresponds to the right edge of the master.
of the container and 1.0 corresponds to the right edge of the container.
\fILocation\fR need not be in the range 0.0\-1.0.
If both \fB\-x\fR and \fB\-relx\fR are specified for a slave
If both \fB\-x\fR and \fB\-relx\fR are specified for a content
then their values are summed.  For example, \fB\-relx 0.5 \-x \-2\fR
positions the left edge of the slave 2 pixels to the left of the
center of its master.
positions the left edge of the content 2 pixels to the left of the
center of its container.
.TP
\fB\-rely \fIlocation\fR
\fILocation\fR specifies the y-coordinate within the master window
\fILocation\fR specifies the y-coordinate within the container window
of the anchor point for \fIwindow\fR.
In this case the value is specified in a relative fashion
as a floating-point number:  0.0 corresponds to the top edge
of the master and 1.0 corresponds to the bottom edge of the master.
of the container and 1.0 corresponds to the bottom edge of the container.
\fILocation\fR need not be in the range 0.0\-1.0.
If both \fB\-y\fR and \fB\-rely\fR are specified for a slave
If both \fB\-y\fR and \fB\-rely\fR are specified for a content
then their values are summed.  For example, \fB\-rely 0.5 \-x 3\fR
positions the top edge of the slave 3 pixels below the
center of its master.
positions the top edge of the content 3 pixels below the
center of its container.
.TP
\fB\-width \fIsize\fR
\fISize\fR specifies the width for \fIwindow\fR in screen units
(i.e. any of the forms accepted by \fBTk_GetPixels\fR).
The width will be the outer width of \fIwindow\fR including its
border, if any.
If \fIsize\fR is an empty string, or if no \fB\-width\fR
or \fB\-relwidth\fR option is specified, then the width requested
internally by the window will be used.
.TP
\fB\-x \fIlocation\fR
\fILocation\fR specifies the x-coordinate within the master window
\fILocation\fR specifies the x-coordinate within the container window
of the anchor point for \fIwindow\fR.
The location is specified in screen units (i.e. any of the forms
accepted by \fBTk_GetPixels\fR) and need not lie within the bounds
of the master window.
of the container window.
.TP
\fB\-y \fIlocation\fR
\fILocation\fR specifies the y-coordinate within the master window
\fILocation\fR specifies the y-coordinate within the container window
of the anchor point for \fIwindow\fR.
The location is specified in screen units (i.e. any of the forms
accepted by \fBTk_GetPixels\fR) and need not lie within the bounds
of the master window.
of the container window.
.PP
If the same value is specified separately with
two different options, such as \fB\-x\fR and \fB\-relx\fR, then
the most recent option is used and the older one is ignored.
.RE
.TP
\fBplace forget \fIwindow\fR
Causes the placer to stop managing the geometry of \fIwindow\fR.  As a
side effect of this command \fIwindow\fR will be unmapped so that it
does not appear on the screen.  If \fIwindow\fR is not currently managed
by the placer then the command has no effect.  This command returns an
empty string.
.TP
\fBplace info \fIwindow\fR
Returns a list giving the current configuration of \fIwindow\fR.
The list consists of \fIoption\-value\fR pairs in exactly the
same form as might be specified to the \fBplace configure\fR
command.
.TP
\fBplace slaves \fIwindow\fR
Returns a list of all the slave windows for which \fIwindow\fR is the master.
If there are no slaves for \fIwindow\fR then an empty string is returned.
\fBplace content \fIwindow\fR
Returns a list of all the content windows for which \fIwindow\fR is the container.
If there is no content for \fIwindow\fR then an empty string is returned.
.TP
\fBplace slaves \fIwindow\fR
.
Synonym for . \fBplace content \fIwindow\fR
.PP
If the configuration of a window has been retrieved with
\fBplace info\fR, that configuration can be restored later by
first using \fBplace forget\fR to erase any existing information
for the window and then invoking \fBplace configure\fR with
the saved information.
.SH "FINE POINTS"
.PP
It is not necessary for the master window to be the parent
of the slave window.
It is not necessary for the container window to be the parent
of the content window.
This feature is useful in at least two situations.
First, for complex window layouts it means you can create a
hierarchy of subwindows whose only purpose
is to assist in the layout of the parent.
The
.QW "real children"
of the parent (i.e. the windows that
are significant for the application's user interface) can be
children of the parent yet be placed inside the windows
of the geometry-management hierarchy.
This means that the path names of the
.QW "real children"
do not reflect the geometry-management hierarchy and users
can specify options for the real children
without being aware of the structure of the geometry-management
hierarchy.
.PP
A second reason for having a master different than the slave's
A second reason for having a container different than the content's
parent is to tie two siblings together.
For example, the placer can be used to force a window always to
be positioned centered just below one of its
siblings by specifying the configuration
.CS
\fB\-in \fIsibling\fB \-relx 0.5 \-rely 1.0 \-anchor n \-bordermode outside\fR
.CE
Whenever the sibling is repositioned in the future, the slave
Whenever the sibling is repositioned in the future, the content
will be repositioned as well.
.PP
Unlike many other geometry managers (such as the packer)
the placer does not make any attempt to manipulate the geometry of
the master windows or the parents of slave windows (i.e. it does not
the container windows or the parents of content windows (i.e. it does not
set their requested sizes).
To control the sizes of these windows, make them windows like
frames and canvases that provide configuration options for this purpose.
.SH EXAMPLE
.PP
Make the label occupy the middle bit of the toplevel, no matter how it
is resized:
.CS
label .l \-text "In the\enMiddle!" \-bg black \-fg white
\fBplace\fR .l \-relwidth .3 \-relx .35 \-relheight .3 \-rely .35
.CE
.SH "SEE ALSO"
grid(n), pack(n)
.SH KEYWORDS
geometry manager, height, location, master, place, rubber sheet, slave, width
geometry manager, height, location, container, place, rubber sheet, content, width
'\" Local Variables:
'\" mode: nroff
'\" End:

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 arg ...\fR?
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for radiobutton widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
.

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 arg ...\fR?
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for scale widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
.

Changes to doc/scrollbar.n.

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







-
+







.SH "WIDGET COMMAND"
.PP
The \fBscrollbar\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for scrollbar widgets:
.TP
\fIpathName \fBactivate \fR?\fIelement\fR?
.
219
220
221
222
223
224
225
226


227
228
229
230
231
232
233
234
235



236
237
238
239
240
241
242
219
220
221
222
223
224
225

226
227
228
229
230
231
232
233
234
235

236
237
238
239
240
241
242
243
244
245







-
+
+








-
+
+
+







.
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.
become visible. Fractional number are rounded away from 0, so
scrolling 0.001 pages has the same effect as scrolling 1 page.
.TP
\fIprefix \fBscroll \fInumber \fBunits\fR
.
The widget should adjust its view by \fInumber\fR units.
The units are defined in whatever way makes sense for the widget,
such as characters or lines in a text widget.
\fINumber\fR is either 1, which means one unit should scroll off
the top or left of the window, or \-1, which means that one unit
should scroll off the bottom or right of the window.
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

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 arg ...\fR?
\fBselection \fIoption\fR ?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
This command provides a Tcl interface to the X selection mechanism and
implements the full selection functionality described in the
X Inter-Client Communication Conventions Manual (ICCCM).
.PP
146
147
148
149
150
151
152
153

154
155
156
157
158
159
160
146
147
148
149
150
151
152

153
154
155
156
157
158
159
160







-
+







.PP
A GUI event, for example \fB<<PasteSelection>>\fR, can copy the \fBPRIMARY\fR selection to certain widgets.  This copy is implemented by a widget binding to the event.  The binding script makes appropriate calls to the \fBselection\fR command.
.PP
.SH PORTABILITY ISSUES
.PP
On X11, the \fBPRIMARY\fR selection is a system-wide feature of the X server, allowing communication between different processes that are X11 clients.
.PP
On Windows, the \fBPRIMARY\fR selection is not provided by the system, but only by Tk, and so it is shared only between windows of a master interpreter and its unsafe slave interpreters.  It is not shared between interpreters in different processes or different threads.  Each master interpreter has a separate \fBPRIMARY\fR selection that is shared only with its unsafe slaves.
On Windows, the \fBPRIMARY\fR selection is not provided by the system, but only by Tk, and so it is shared only between windows of a parent interpreter and its child interpreters.  It is not shared between interpreters in different processes or different threads.  Each parent interpreter has a separate \fBPRIMARY\fR selection that is shared only with its child interpreters which are not safe interpreters.
.PP
.SH SECURITY
.PP
A safe interpreter cannot read from the \fBPRIMARY\fR selection because its \fBselection\fR command is hidden.  For this reason the \fBPRIMARY\fR selection cannot be written to the Tk widgets of a safe interpreter.
.PP
A Tk widget can have its option \fB\-exportselection\fR set to boolean \fBtrue\fR, but in a safe interpreter this option has no effect: writing from the widget to the \fBPRIMARY\fR selection is disabled.
.PP

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 arg ...\fR?
\fBsend ?\fIoptions\fR? \fIapp cmd \fR?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
This command arranges for \fIcmd\fR (and \fIarg\fRs) to be executed in the
application named by \fIapp\fR.  It returns the result or
error from that command execution.
\fIApp\fR may be the name of any application whose main window is

Changes to doc/spinbox.n.

220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235
236
237
238
239
240
241
242

243
244
245
246
247
248
249
220
221
222
223
224
225
226

227
228
229
230
231
232
233
234
235
236
237
238
239
240
241

242
243
244
245
246
247
248
249







-
+














-
+







associated \fB\-textvariable\fR during validation, as that can cause the
spinbox widget to become out of sync with the \fB\-textvariable\fR.
.PP
Also, the \fB-validate\fR option will set itself to \fBnone\fR when the
spinbox value gets changed because of adjustment of \fB-from\fR or \fB-to\fR
and the \fB-validatecommand\fR returns false. For instance
.CS
     \fIspinbox pathName \-from 1 \-to 10 \-validate all \-vcmd {return 0}\fR
     \fIspinbox pathName \-from 1 \-to 10 \-validate all \-validatecommand {return 0}\fR
.CE
will in fact set the \fB-validate\fR option to \fBnone\fR because the default
value for the spinbox gets changed (due to the \fB-from\fR and \fB-to\fR
options) to a value not accepted by the validation script.
.PP
Moreover, forced validation is performed when invoking any spinbutton of
the spinbox. If the validation script returns false in this situation,
then the \fB-validate\fR option will be automatically set to \fBnone\fR.
.SH "WIDGET COMMAND"
.PP
The \fBspinbox\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
.SS INDICES
.PP
Many of the widget commands for spinboxes take one or more indices as
arguments.  An index specifies a particular character in the spinbox's
466
467
468
469
470
471
472
473


474
475
476
477
478
479
480
466
467
468
469
470
471
472

473
474
475
476
477
478
479
480
481







-
+
+







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.
\fINumber\fR must be an integer or a float, but if it is a float then
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR or an abbreviation
of one of these.
If \fIwhat\fR is \fBpages\fR then the view adjusts by \fInumber\fR
screenfuls. If \fInumber\fR is negative then characters farther to the left
become visible;  if it is positive then characters farther to the right
become visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by

Added doc/sysnotify.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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
.\" Text automatically generated by txt2man
'\"
'\" Copyright (c) 2020 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.
'\"
.TH tk sysnotify n "" Tk "Tk Built-In Commands"
.so man.macros
.SH NAME
sysnotify \- Creates a notification window with a title and message.
.SH SYNOPSIS
\fBtk sysnotify\fR \fItitle\fR \fImessage\fR
.BE
.SH DESCRIPTION
.PP
The \fBtk sysnotify\fR command creates a platform-specific system notification alert. Its intent is to provide a brief, unobtrusive notification to the user by popping up a window that briefly appears in a corner of the screen.
.SH EXAMPLE
.PP
Here is an example of the \fBtk sysnotify\fR code:
.CS
     tk sysnotify "Alert" "This is just a test of the Tk System Notification Code."
.CE
.SH PLATFORM NOTES
.PP
The macOS and Windows versions are native implementations using system
API's. The X11 version has a conditional dependency on libnotify, and
falls back to a Tcl-only implementation if libnotify is not installed. On
each platform the notification includes a platform-specific default image to
accompany the text.
.
.TP
\fBmacOS\fR
.
The macOS version embeds two separate under-the-hood implementations
using different notification APIs.  The choice of which one to use
depends on which version of the OS is being run and the state of the
Tk application code. The newer API, introduced in macOS 10.14,
requires that the application accessing the API be code-signed, or the
notification will not display.  (A self-signed certificate seems to be
sufficient.) The older API was deprecated but not removed in macOS
11.0. Tk uses the newer API only for signed applications running on
macOS 10.14 or newer.  Otherwise it falls back to the older API.  A
quirk which developers should be aware of is that if an unsigned
version of Wish (or an application derived from it) is installed on
top of a signed version after the signed version has been registered
with System Preferences then neither API will be allowed to show
notifications, making Tk's automatic fallback to the older API
ineffective.  To re-enable notifications the application must be
deleted from Apple's System Preferences Notifications section. (There
is no removal button, so this is done by selecting the application and
pressing the Delete key.)
.
.TP
\fBWindows\fR
.
The image is taken from the systray i.e. a sysnotify can only be
called when a systray was installed.
.
.SH KEYWORDS
notify, alert

Added doc/systray.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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
.\" Text automatically generated by txt2man
'\"
'\" Copyright (c) 2020 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.
'\"
.TH tk systray n "" Tk "Tk Built-In Commands"
.so man.macros
.SH NAME
systray \- Creates an icon display in the platform-specific system tray.
.SH SYNOPSIS
\fBtk systray create \fI-image image\fR \fI?-text text\fR? \fI?-button1 callback?\fR \fI?-button3 callback?\fR
.sp
\fBtk systray configure \fI?option? ?value option value ...?\fR
.sp
\fBtk systray destroy\fR
.BE
.BE
.SH DESCRIPTION
.PP
The \fBtk systray create\fR command creates an icon in the platform-specific
tray. The widget is configured with a Tk image for the icon display, an
optional string for display in a tooltip, and optional callbacks that are
bound to <Button-1> and <Button-3>.
.PP
The \fBtk systray configure\fR command sets one or more options of the systray
icon. Configurable options are the same as for the \fBcreate\fR subcommand. When
a single option name is given, the command returns the current valus of this
option. When no option is given this command returns the list of all options and
their current value.
.PP
 The \fBtk systray destroy\fR command removes the icon from display and
deallocates it.
.PP
From a user-interface standpoint, only one icon per interpreter is
supported; attempts to create additional icons will return an error. The
existing tray icon can be modified with different images and
strings to indicate app state. Loading additional interpreters into a
running instance of Wish will allow additional icons to be displayed.
.SH EXAMPLE
.PP
Here is an example of the \fBtk systray\fR code:
.CS
    image create photo book -data R0lGODlhDwAPAKIAAP//////AP8AAMDAwICAgAAAAAAAAAAAACwAAAAADwAPAAADSQhA2u5ksPeKABKSCaya29d4WKgERFF0l1IMQCAKatvBJ0OTdzzXI1xMB3TBZAvATtB6NSLKleXi3OBoLqrVgc0yv+DVSEUuFxIAOw==
    tk systray create -image book -text "tk systray sample" -button1 {puts "Here is the tk systray output"} -button3 {puts "here is alternate output"}
.CE
.PP
Here is an example of modifying the \fBtk systray\fR icon:
.CS
    image create photo book_page -data R0lGODlhCwAPAKIAAP//////AMDAwICAgAAA/wAAAAAAAAAAACwAAAAACwAPAAADMzi6CzAugiAgDGE68aB0RXgRJBFVX0SNpQlUWfahQOvSsgrX7eZJMlQMWBEYj8iQchlKAAA7
    tk systray configure -image book_page -text "Updated sample" -button1 {puts "Different output from the tk systray"} -button3 {puts "and more different output from the tk systray"}
.CE
.SH PLATFORM NOTES
.PP
The X11 implementation is supported on a "best efforts" basis because it is
dependent on the window manager. The "text" flag, which is implemented as
a tooltip, does not always display if the WM does not support such features;
the systray icon itself may not even display with some window managers.
.PP
On Windows, the Tk image provided in the \fI-image\fR option must be a
photo image. On other platforms either a bitmap image or a photo image
may be provided.
.SH KEYWORDS
image, callback

Changes to doc/text.n.

1048
1049
1050
1051
1052
1053
1054
1055

1056
1057
1058
1059
1060
1061
1062
1048
1049
1050
1051
1052
1053
1054

1055
1056
1057
1058
1059
1060
1061
1062







-
+







.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 arg ...\fR?
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIPathName\fR is the name of the command, which is the same as the text
widget's path name. \fIOption\fR and the \fIarg\fRs determine the exact
behavior of the command. The following commands are possible for text widgets:
.TP
\fIpathName \fBbbox \fIindex\fR
.
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
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







-
+












-
+







Compares the indices given by \fIindex1\fR and \fIindex2\fR according to the
relational operator given by \fIop\fR, and returns 1 if the relationship is
satisfied and 0 if it is not. \fIOp\fR must be one of the operators <, <=, ==,
>=, >, or !=. If \fIop\fR is == then 1 is returned if the two indices refer to
the same character, if \fIop\fR is < then 1 is returned if \fIindex1\fR refers
to an earlier character in the text than \fIindex2\fR, and so on.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? \fI?value option value ...\fR?
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget. If no \fIoption\fR is
specified, returns a list describing all of the available options for
\fIpathName\fR (see \fBTk_ConfigureInfo\fR for information on the format of
this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command
returns a list describing the one named option (this list will be identical to
the corresponding sublist of the value returned if no \fIoption\fR is
specified). If one or more \fIoption\-value\fR pairs are specified, then the
command modifies the given widget option(s) to have the given value(s); in
this case the command returns an empty string. \fIOption\fR may have any of
the values accepted by the \fBtext\fR command.
.TP
\fIpathName \fBcount\fR \fI?options\fR? \fIindex1 index2\fR
\fIpathName \fBcount\fR ?\fIoptions\fR? \fIindex1 index2\fR
.
Counts the number of relevant things between the two indices. If \fIindex1\fR
is after \fIindex2\fR, the result will be a negative number (and this holds
for each of the possible options). The actual items which are counted depend
on the options given. The result is a list of integers, one for the result of
each counting option given. Valid counting options are \fB\-chars\fR,
\fB\-displaychars\fR, \fB\-displayindices\fR, \fB\-displaylines\fR,
1277
1278
1279
1280
1281
1282
1283
1284

1285
1286
1287
1288
1289
1290
1291
1277
1278
1279
1280
1281
1282
1283

1284
1285
1286
1287
1288
1289
1290
1291







-
+







.
Include information about embedded windows in the dump results. The value of a
window is its Tk pathname, unless the window has not been created yet. (It
must have a create script.) In this case an empty string is returned, and you
must query the window by its index position to get more information.
.RE
.TP
\fIpathName \fBedit \fIoption \fR?\fIarg arg ...\fR?
\fIpathName \fBedit \fIoption \fR?\fIarg ...\fR?
.
This command controls the undo mechanism and the modified flag. The exact
behavior of the command depends on the \fIoption\fR argument that follows the
\fBedit\fR argument. The following forms of the command are currently
supported:
.RS
.TP
1345
1346
1347
1348
1349
1350
1351
1352

1353
1354
1355

1356
1357
1358
1359
1360
1361
1362
1345
1346
1347
1348
1349
1350
1351

1352
1353
1354

1355
1356
1357
1358
1359
1360
1361
1362







-
+


-
+







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 arg ...\fR?
\fIpathName \fBimage \fIoption \fR?\fIarg ...\fR?
.
This command is used to manipulate embedded images. The behavior of the
command depends on the \fIoption\fR argument that follows the \fBtag\fR
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
1410
1411
1412
1413
1414
1415
1416

1417
1418
1419
1420
1421
1422
1423
1424







-
+







characters will receive all of the tags in this list and no others, regardless
of the tags present around the insertion point. If multiple
\fIchars\fR\-\fItagList\fR argument pairs are present, they produce the same
effect as if a separate \fIpathName \fBinsert\fR widget command had been
issued for each pair, in order. The last \fItagList\fR argument may be
omitted.
.TP
\fIpathName \fBmark \fIoption \fR?\fIarg arg ...\fR?
\fIpathName \fBmark \fIoption \fR?\fIarg ...\fR?
.
This command is used to manipulate marks. The exact behavior of the command
depends on the \fIoption\fR argument that follows the \fBmark\fR argument. The
following forms of the command are currently supported:
.RS
.TP
\fIpathName \fBmark gravity \fImarkName\fR ?\fIdirection\fR?
1690
1691
1692
1693
1694
1695
1696
1697

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

1697
1698
1699
1700
1701
1702
1703
1704







-
+







\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 arg ...\fR?
\fIpathName \fBtag \fIoption \fR?\fIarg ...\fR?
.
This command is used to manipulate tags. The exact behavior of the command
depends on the \fIoption\fR argument that follows the \fBtag\fR argument. The
following forms of the command are currently supported:
.RS
.TP
\fIpathName \fBtag add \fItagName index1 \fR?\fIindex2 index1 index2 ...\fR?
1857
1858
1859
1860
1861
1862
1863
1864

1865
1866
1867
1868
1869
1870
1871
1857
1858
1859
1860
1861
1862
1863

1864
1865
1866
1867
1868
1869
1870
1871







-
+







\fIindex1\fR\-\fIindex2\fR pairs. If the last \fIindex2\fR is omitted then the
tag is removed from the single character at \fIindex1\fR. If there are no
characters in the specified range (e.g. \fIindex1\fR is past the end of the
file or \fIindex2\fR is less than or equal to \fIindex1\fR) then the command
has no effect. This command returns an empty string.
.RE
.TP
\fIpathName \fBwindow \fIoption \fR?\fIarg arg ...\fR?
\fIpathName \fBwindow \fIoption \fR?\fIarg ...\fR?
.
This command is used to manipulate embedded windows. The behavior of the
command depends on the \fIoption\fR argument that follows the \fBwindow\fR
argument. The following forms of the command are currently supported:
.RS
.TP
\fIpathName \fBwindow cget \fIindex option\fR

Changes to doc/tk.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 tk n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk \- Manipulate Tk internal state
.SH SYNOPSIS
\fBtk\fR \fIoption \fR?\fIarg arg ...\fR?
\fBtk\fR \fIoption \fR?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
The \fBtk\fR command provides access to miscellaneous
elements of Tk's internal state.
Most of the information manipulated by this command pertains to the
application as a whole, or to a screen or display, rather than to a
107
108
109
110
111
112
113












114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

131
132

133
134
135
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

142
143

144
145
146
147







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
















-
+

-
+



factor is set when the application starts, based on properties of the
installed monitor, but it can be changed at any time.  Measurements made
after the scaling factor is changed will use the new scaling factor, but it
is undefined whether existing widgets will resize themselves dynamically to
accommodate the new scaling factor.
.RE
.TP
\fBtk sysnotify \fP \fItitle\fP? \fImessage\fP?
.
The \fBtk sysnotify\fP  command creates a platform-specific system
notification alert. Its intent is to provide a brief, unobtrusive
notification to the user by popping up a window that briefly appears in a
corner of the screen. For more details see the  see the \fBsysnotify\fR manual page.
.TP
\fBtk systray create\fP \fIsubcommand...\fP
.
The \fBtk systray\fP command creates an icon in the platform-specific
tray. For more details see the  see the \fBsystray\fR manual page.
.TP
\fBtk useinputmethods \fR?\fB\-displayof \fIwindow\fR? ?\fIboolean\fR?
.
Sets and queries the state of whether Tk should use XIM (X Input Methods)
for filtering events.  The resulting state is returned.  XIM is used in
some locales (i.e., Japanese, Korean), to handle special input devices. This
feature is only significant on X.  If XIM support is not available, this
will always return 0.  If the \fIwindow\fR argument is omitted, it defaults
to the main window.  If the \fIboolean\fR argument is omitted, the current
state is returned.  This is turned on by default for the main display.
.TP
\fBtk windowingsystem\fR
.
Returns the current Tk windowing system, one of
\fBx11\fR (X11-based), \fBwin32\fR (MS Windows),
or \fBaqua\fR (Mac OS X Aqua).
.SH "SEE ALSO"
busy(n), fontchooser(n), send(n), winfo(n)
busy(n), fontchooser(n), send(n), sysnotify(n), systray(n), winfo(n)
.SH KEYWORDS
application name, send
application name, send, sysnotify, systray
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/tk_mac.n.

214
215
216
217
218
219
220
221
222
223
224








225



226
227
228
229
230
231
232
214
215
216
217
218
219
220




221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
236
237
238







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







.SH "ADDITIONAL DIALOGS"
.PP
The Aqua/Mac OS X defines additional dialogs that applications should
support.
.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.
.TP
\fB::tk::mac::useCompatibilityMetrics \fIboolean\fR
.

Changes to doc/tkvars.n.

46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60







-
+







Contains a dot-separated sequence of decimal integers giving the
current patch level for Tk.
The patch level is incremented for each new release or patch, and
it uniquely identifies an official version of Tk.
.RS
.PP
This value is normally the same as the result of
.QW "\fBpackage require\fR \fBTk\fR" .
.QW "\fBpackage require\fR \fBtk\fR" .
.RE
.TP
\fBtk_strictMotif\fR
.
This variable is set to zero by default.
If an application sets it to one, then Tk attempts to adhere as
closely as possible to Motif look-and-feel standards.

Changes to doc/toplevel.n.

36
37
38
39
40
41
42
43



44
45
46
47
48
49
50
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50
51
52







-
+
+
+







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
135
136
137
138
139
140
141
142

143
144
145
146
147
148
149
137
138
139
140
141
142
143

144
145
146
147
148
149
150
151







-
+







.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 arg ...\fR?
\fIpathName option \fR?\fIarg ...\fR?
.CE
.PP
\fIPathName\fR is the name of the command, which is the same as
the toplevel widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for toplevel widgets:
.TP

Changes to doc/ttk_Geometry.3.

62
63
64
65
66
67
68

69
70

71
72
73
74
75
76
77
78
79
80
81

82
83

84
85
86
87
88

89
90
91
92
93
94
95
96
97
98

99
100
101
102
103
104




105
106
107
108
109
110
111
62
63
64
65
66
67
68
69
70

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

85
86
87
88
89

90
91
92
93
94
95
96
97
98
99

100
101
102




103
104
105
106
107
108
109
110
111
112
113







+

-
+











+

-
+




-
+









-
+


-
-
-
-
+
+
+
+







.AP "Ttk_Box *" cavity in/out
A rectangular region from which a parcel is allocated.
.AP short border in
Extra padding (in pixels) to add uniformly to each side of a region.
.AP short bottom in
Extra padding (in pixels) to add to the bottom of a region.
.AP Ttk_Box box in
Specifies a rectangular region.
.AP "Ttk_Box *" box_rtn out
Specifies a rectangular region.
A rectangular region.
.AP int height in
The height in pixels of a region.
.AP "Tcl_Interp *" interp in
Used to store error messages.
.AP int left in
Extra padding (in pixels) to add to the left side of a region.
.AP "Tcl_Obj *" objPtr in
String value contains a symbolic name
to be converted to an enumerated value or bitmask.
Internal rep may be be modified to cache corresponding value.
.AP Ttk_Padding padding in
Extra padding to add on the inside of a region.
.AP "Ttk_Padding *" padding_rtn out
Extra padding to add on the inside of a region.
Padding present in the inside of a region.
.AP Ttk_Box parcel in
A rectangular region, allocated from a cavity.
.AP int relief in
One of the standard Tk relief options
(TK_RELIEF_RAISED, TK_RELIEF_SUNKEN, etc.).
(\fBTK_RELIEF_RAISED\fR, \fBTK_RELIEF_SUNKEN\fR, etc.).
See \fBTk_GetReliefFromObj\fR.
.AP short right in
Extra padding (in pixels) to add to the right side of a region.
.AP Ttk_Side side in
One of \fBTTK_SIDE_LEFT\fR, \fBTTK_SIDE_TOP\fR,
\fBTTK_SIDE_RIGHT\fR, or \fBTTK_SIDE_BOTTOM\fR.
.AP unsigned sticky in
A bitmask containing one or more of the bits
\fBTTK_STICK_W\fR (west, or left),
\fBTTK_STICK_E\fR (east, or right,
\fBTTK_STICK_E\fR (east, or right),
\fBTTK_STICK_N\fR (north, or top), and
\fBTTK_STICK_S\fR (south, or bottom).
\fBTTK_FILL_X\fR is defined as a synonym for (TTK_STICK_W|TTK_STICK_E),
\fBTTK_FILL_Y\fR is a synonym for (TTK_STICK_N|TTK_STICK_S),
and  \fBTTK_FILL_BOTH\fR and \fBTTK_STICK_ALL\fR
are synonyms for (TTK_FILL_X|TTK_FILL_Y).
\fBTTK_FILL_X\fR is defined as a synonym for (\fBTTK_STICK_W\fR|\fBTTK_STICK_E\fR),
\fBTTK_FILL_Y\fR is a synonym for (\fBTTK_STICK_N\fR|\fBTTK_STICK_S\fR),
and  \fBTTK_FILL_BOTH\fR
is a synonym for (\fBTTK_FILL_X\fR|\fBTTK_FILL_Y\fR).
See also: \fIgrid(n)\fR.
.AP Tk_Window tkwin in
Window whose screen geometry determines
the conversion between absolute units and pixels.
.AP short top in
Extra padding at the top of a region.
.AP int width in

Changes to doc/ttk_button.n.

44
45
46
47
48
49
50
51
52




53
54
55
56
57
58
59
44
45
46
47
48
49
50


51
52
53
54
55
56
57
58
59
60
61







-
-
+
+
+
+







.\" .OP \-foreground foreground Foreground
.\" .OP \-font font Font
.\" .OP \-anchor anchor Anchor
.\" .OP \-relief relief Relief
.SH "WIDGET COMMAND"
.PP
In addition to the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR
commands, buttons support the following additional widget commands:
\fBcget\fR, \fBconfigure\fR, \fBidentify element\fR, \fBinstate\fR,
\fBstate\fR and \fBstyle\fR
commands (see \fBttk::widget\fR),
button widgets support the following additional commands:
.TP
\fIpathName \fBinvoke\fR
Invokes the command associated with the button.
.SH "STANDARD STYLES"
.PP
\fBTtk::button\fR widgets support the \fBToolbutton\fR style in all standard
themes, which is useful for creating widgets for toolbars.

Changes to doc/ttk_checkbutton.n.

33
34
35
36
37
38
39
40
41




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


40
41
42
43

44
45
46
47
48
49
50







-
-
+
+
+
+
-







when the widget is selected.  Defaults to \fB1\fR.
.OP \-variable variable Variable
The name of a global variable whose value is linked to the widget.
Defaults to the widget pathname if not specified.
.SH "WIDGET COMMAND"
.PP
In addition to the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR
commands, checkbuttons support the following additional
\fBcget\fR, \fBconfigure\fR, \fBidentify element\fR, \fBinstate\fR,
\fBstate\fR and \fBstyle\fR
commands (see \fBttk::widget\fR),
checkbutton widgets support the following additional commands:
widget commands:
.TP
\fIpathname\fB invoke\fR
Toggles between the selected and deselected states
and evaluates the associated \fB\-command\fR.
If the widget is currently selected, sets the \fB\-variable\fR
to the \fB\-offvalue\fR and deselects the widget;
otherwise, sets the \fB\-variable\fR to the \fB\-onvalue\fR

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
\-style	\-placeholder	\-placeholderforeground
.SE
.\" ALSO: Other entry widget options
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-exportselection exportSelection ExportSelection
Boolean value.
If set, the widget selection is linked to the X selection.
.OP \-justify justify Justify
51
52
53
54
55
56
57
58

59
60

61
62


63
64
65

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

96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
51
52
53
54
55
56
57

58


59


60
61



62

63
64
65
66
67
68
69
70
71
72
73








74
75
76




77
78

79
80
81
82
83
84
85







86
87
88
89
90
91
92







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











-
-
-
-
-
-
-
-



-
-
-
-


-
+






-
-
-
-
-
-
-







.OP \-values values Values
Specifies the list of values to display in the drop-down listbox.
.OP \-width width Width
Specifies an integer value indicating the desired width of the entry window,
in average-size characters of the widget's font.
.SH "WIDGET COMMAND"
.PP
The following subcommands are possible for combobox widgets:
In addition to the standard
'\".TP
'\"\fIpathName \fBcget\fR \fIoption\fR
\fBcget\fR, \fBconfigure\fR, \fBidentify element\fR, \fBinstate\fR,
'\"Returns the current value of the specified \fIoption\fR.
'\"See \fIttk::widget(n)\fR.
\fBstate\fR and \fBstyle\fR
commands (see \fBttk::widget\fR),
'\".TP
'\"\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
'\"Modify or query widget options.
combobox widgets support the following additional commands:
'\"See \fIttk::widget(n)\fR.
.TP
\fIpathName \fBcurrent\fR ?\fInewIndex\fR?
If \fInewIndex\fR is supplied, sets the combobox value
to the element at position \fInewIndex\fR in the list of \fB\-values\fR
(in addition to integers, the \fBend\fR index is supported and indicates
the last element of the list).
Otherwise, returns the index of the current value in the list of
\fB\-values\fR or \fB\-1\fR if the current value does not appear in the list.
.TP
\fIpathName \fBget\fR
Returns the current value of the combobox.
'\".TP
'\"\fIpathName \fBidentify \fIx y\fR
'\"Returns the name of the element at position \fIx\fR, \fIy\fR.
'\"See \fIttk::widget(n)\fR.
'\".TP
'\"\fIpathName \fBinstate \fIstateSpec\fR ?\fIscript\fR?
'\"Test the widget state.
'\"See \fIttk::widget(n)\fR.
.TP
\fIpathName \fBset\fR \fIvalue\fR
Sets the value of the combobox to \fIvalue\fR.
'\".TP
'\"\fIpathName \fBstate\fR ?\fIstateSpec\fR?
'\"Modify or query the widget state.
'\"See \fIttk::widget(n)\fR.
.PP
The combobox widget also supports the following \fBttk::entry\fR
widget subcommands (see \fIttk::entry(n)\fR for details):
widget commands:
.DS
.ta 5.5c 11c
\fBbbox\fR	\fBdelete\fR	\fBicursor\fR
\fBindex\fR	\fBinsert\fR	\fBselection\fR
\fBxview\fR
.DE
The combobox widget also supports the following generic \fBttk::widget\fR
widget subcommands (see \fIttk::widget(n)\fR for details):
.DS
.ta 5.5c 11c
\fBcget\fR	\fBconfigure\fR	\fBidentify\fR
\fBinstate\fR	\fBstate\fR
.DE
.SH "VIRTUAL EVENTS"
.PP
The combobox widget generates a \fB<<ComboboxSelected>>\fR virtual event
when the user selects an element from the list of values.
If the selection action unposts the listbox,
this event is delivered after the listbox is unposted.
.SH "STYLING OPTIONS"
138
139
140
141
142
143
144


145
146
147
148
149


150
151
152
153
154
155
156
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137







+
+





+
+







.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-fieldbackground\fP \fIcolor\fP
.RS
Can only be changed when using non-native and non-graphical themes.
.RE
\fB\-insertcolor\fP \fIcolor\fP
.br
\fB\-insertwidth\fP \fIamount\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.br
\fB\-placeholderforeground\fP \fIcolor\fP
.br
\fB\-postoffset\fP \fIpadding\fP
.br
\fB\-selectbackground\fP \fIcolor\fP
.RS
Text entry select background.
.RE

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
\-takefocus	\-xscrollcommand	\-placeholder	\-placeholderforeground
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-exportselection exportSelection ExportSelection
A boolean value specifying whether or not
a selection in the widget should be linked to the X selection.
If the selection is exported, then selecting in the widget deselects
the current X selection, selecting outside the widget deselects any
135
136
137
138
139
140
141




142

143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
135
136
137
138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
153
154
155
156








157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172




173
174
175
176
177
178
179




180
181
182
183
184
185
186







+
+
+
+
-
+










-
-
-
-
-
-
-
-
















-
-
-
-







-
-
-
-







.QW \fBe\fR
or
.QW \fBsel.l\fR .
In general, out-of-range indices are automatically rounded to the
nearest legal value.
.SH "WIDGET COMMAND"
.PP
In addition to the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify element\fR, \fBinstate\fR,
\fBstate\fR, \fBstyle\fR and \fBxview\fR
commands (see \fBttk::widget\fR),
The following subcommands are possible for entry widgets:
entry widgets support the following additional commands:
.TP
\fIpathName \fBbbox \fIindex\fR
Returns a list of four numbers describing the bounding box of the
character given by \fIindex\fR.
The first two elements of the list give the x and y coordinates of
the upper-left corner of the screen area covered by the character
(in pixels relative to the widget) and the last two elements give
the width and height of the character, in pixels.
The bounding box may refer to a region outside the visible area
of the window.
'\".TP
'\"\fIpathName \fBcget\fR \fIoption\fR
'\"Returns the current value of the specified \fIoption\fR.
'\"See \fIttk::widget(n)\fR.
'\".TP
'\"\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
'\"Modify or query widget options.
'\"See \fIttk::widget(n)\fR.
.TP
\fIpathName \fBdelete \fIfirst \fR?\fIlast\fR?
Delete one or more elements of the entry.
\fIFirst\fR is the index of the first character to delete, and
\fIlast\fR is the index of the character just after the last
one to delete.
If \fIlast\fR is not specified it defaults to \fIfirst\fR+1,
i.e. a single character is deleted.
This command returns the empty string.
.TP
\fIpathName \fBget\fR
Returns the entry's string.
.TP
\fIpathName \fBicursor \fIindex\fR
Arrange for the insert cursor to be displayed just before the character
given by \fIindex\fR.  Returns the empty string.
'\".TP
'\"\fIpathName \fBidentify \fIx y\fR
'\"Returns the name of the element at position \fIx\fR, \fIy\fR,
'\"or the empty string if the coordinates are outside the window.
.TP
\fIpathName \fBindex\fI index\fR
Returns the numerical index corresponding to \fIindex\fR.
.TP
\fIpathName \fBinsert \fIindex string\fR
Insert \fIstring\fR just before the character
indicated by \fIindex\fR.  Returns the empty string.
'\".TP
'\"\fIpathName \fBinstate \fIstatespec\fR ?\fIscript\fR?
'\"Test the widget state.
'\"See \fIttk::widget(n)\fR.
.TP
\fIpathName \fBselection \fIoption arg\fR
This command is used to adjust the selection within an entry.  It
has several forms, depending on \fIoption\fR:
.RS
.TP
\fIpathName \fBselection clear\fR
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
195
196
197
198
199
200
201




202
203
204
205
206
207
208








209
210
211
212
213
214
215







-
-
-
-







-
-
-
-
-
-
-
-







\fIpathName \fBselection range \fIstart\fR \fIend\fR
Sets the selection to include the characters starting with
the one indexed by \fIstart\fR and ending with the one just
before \fIend\fR.
If \fIend\fR refers to the same character as \fIstart\fR or an
earlier one, then the entry's selection is cleared.
.RE
'\".TP
'\"\fIpathName \fBstate\fR ?\fIstateSpec\fR?
'\"Modify or query the widget state.
'\"See \fIttk::widget(n)\fR.
.TP
\fIpathName \fBvalidate\fR
Force revalidation, independent of the conditions specified
by the \fB\-validate\fR option.
Returns 0 if validation fails, 1 if it succeeds.
Sets or clears the \fBinvalid\fR state accordingly.
See \fBVALIDATION\fR below for more details.
.PP
The entry widget also supports the following generic \fBttk::widget\fR
widget subcommands (see \fIttk::widget(n)\fR for details):
.DS
.ta 5.5c 11c
\fBcget\fR	\fBconfigure\fR	\fBidentify\fR
\fBinstate\fR	\fBstate\fR	\fBxview\fR
.DE
.SH VALIDATION
.PP
The \fB\-validate\fR, \fB\-validatecommand\fR, and \fB\-invalidcommand\fR
options are used to enable entry widget validation.
.SS "VALIDATION MODES"
.PP
There are two main validation modes: \fIprevalidation\fR,
443
444
445
446
447
448
449


450
451
452
453
454
455


456
457
458
459
460
461
462
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442







+
+






+
+







\fB\-darkcolor\fP \fIcolor\fP
.br
\fB\-fieldbackground\fP \fIcolor\fP
.RS
Some themes use a graphical background and their field background colors cannot be changed.
.RE
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-insertcolor\fP \fIcolor\fP
.br
\fB\-insertwidth\fP \fIamount\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.br
\fB\-placeholderforeground\fP \fIcolor\fP
.br
\fB\-relief\fP \fIrelief\fP
.br
\fB\-selectbackground\fP \fIcolor\fP
.br
\fB\-selectborderwidth\fP \fIamount\fP
.br

Changes to doc/ttk_frame.n.

31
32
33
34
35
36
37
38
39
40




41
42
43
44
45
46
47
31
32
33
34
35
36
37



38
39
40
41
42
43
44
45
46
47
48







-
-
-
+
+
+
+







Defaults to \fBflat\fR.
.OP \-width width Width
If specified, the widget's requested width in pixels.
.OP \-height height Height
If specified, the widget's requested height in pixels.
.SH "WIDGET COMMAND"
.PP
Supports the standard widget commands
\fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR;
see \fIttk::widget(n)\fR.
Frame widgets support the standard commands
\fBcget\fR, \fBconfigure\fR, \fBidentify element\fR, \fBinstate\fR,
\fBstate\fR and \fBstyle\fR
(see \fBttk::widget\fR).
.SH "NOTES"
.PP
Note that if the \fBpack\fR, \fBgrid\fR, or other geometry managers
are used to manage the children of the \fBframe\fR,
by the GM's requested size will normally take precedence
over the \fBframe\fR widget's \fB\-width\fR and \fB\-height\fR options.
\fBpack propagate\fR and \fBgrid propagate\fR can be used

Changes to doc/ttk_intro.n.

82
83
84
85
86
87
88
89

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

89
90
91
92
93
94
95
96







-
+







For example, the layout for a horizontal scrollbar is:
.PP
.CS
ttk::\fBstyle layout\fR Horizontal.TScrollbar {
    Scrollbar.trough \-children {
	Scrollbar.leftarrow \-side left \-sticky w
	Scrollbar.rightarrow \-side right \-sticky e
	Scrollbar.thumb \-side left \-expand true \-sticky ew
	Scrollbar.thumb \-sticky ew
    }
}
.CE
.PP
By default, the layout for a widget is the same as its class name.
Some widgets may override this (for example, the \fBttk::scrollbar\fR
widget chooses different layouts based on the \fB\-orient\fR option).

Changes to doc/ttk_label.n.

38
39
40
41
42
43
44
45
46
47




48
49
50
51
52
53
54
38
39
40
41
42
43
44



45
46
47
48
49
50
51
52
53
54
55







-
-
-
+
+
+
+







Specifies the maximum line length (in pixels).
If this option is less than or equal to zero,
then automatic wrapping is not performed; otherwise
the text is split into lines such that no line is longer
than the specified value.
.SH "WIDGET COMMAND"
.PP
Supports the standard widget commands
\fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR;
see \fIttk::widget(n)\fR.
Label widgets support the standard commands
\fBcget\fR, \fBconfigure\fR, \fBidentify element\fR, \fBinstate\fR,
\fBstate\fR and \fBstyle\fR
(see \fBttk::widget\fR).
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::label\fP is \fBTLabel\fP.
.PP
Dynamic states: \fBdisabled\fP, \fBreadonly\fP.
.PP
\fBTLabel\fP styling options configurable with \fBttk::style\fP

Changes to doc/ttk_labelframe.n.

58
59
60
61
62
63
64
65
66
67




68
69
70
71
72
73
74
58
59
60
61
62
63
64



65
66
67
68
69
70
71
72
73
74
75







-
-
-
+
+
+
+







The underlined character is used for mnemonic activation.
Mnemonic activation for a \fBttk::labelframe\fR
sets the keyboard focus to the first child of the \fBttk::labelframe\fR widget.
.OP \-width width Width
If specified, the widget's requested width in pixels.
.SH "WIDGET COMMAND"
.PP
Supports the standard widget commands
\fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR;
see \fIttk::widget(n)\fR.
Labelframe widgets support the standard commands
\fBcget\fR, \fBconfigure\fR, \fBidentify element\fR, \fBinstate\fR,
\fBstate\fR and \fBstyle\fR
(see \fBttk::widget\fR).
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::labelframe\fP is \fBTLabelframe\fP.
The text label
has a class of \fBTLabelframe.Label\fP.
.PP
Dynamic states: \fBdisabled\fP, \fBreadonly\fP.

Changes to doc/ttk_menubutton.n.

34
35
36
37
38
39
40
41
42
43




44
45
46
47
48
49
50
34
35
36
37
38
39
40



41
42
43
44
45
46
47
48
49
50
51







-
-
-
+
+
+
+







To be on the safe side, the menu ought to be a direct child of the
menubutton.
.\" not documented: may go away:
.\" .OP \-anchor anchor Anchor
.\" .OP \-padding padding Pad
.SH "WIDGET COMMAND"
.PP
Menubutton widgets support the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR
methods.  No other widget methods are used.
Menubutton widgets support the standard commands
\fBcget\fR, \fBconfigure\fR, \fBidentify element\fR, \fBinstate\fR,
\fBstate\fR and \fBstyle\fR
(see \fBttk::widget\fR).
.SH "STANDARD STYLES"
.PP
\fBTtk::menubutton\fR widgets support the \fBToolbutton\fR style in all
standard themes, which is useful for creating widgets for toolbars.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::menubutton\fP is \fBTMenubutton\fP.

Changes to doc/ttk_notebook.n.

16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
16
17
18
19
20
21
22

23
24
25
26
27
28
29
30







-
+







\fIpathname \fBadd\fR \fIwindow\fR ?\fIoptions...\fR?
\fIpathname \fBinsert\fR \fIindex\fR \fIwindow\fR ?\fIoptions...\fR?
.fi
.BE
.SH DESCRIPTION
A \fBttk::notebook\fR widget manages a collection of windows
and displays a single one at a time.
Each slave window is associated with a \fItab\fR,
Each content window is associated with a \fItab\fR,
which the user may select to change the currently-displayed window.
.SO ttk_widget
\-class	\-cursor	\-takefocus
\-style
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-height height Height
52
53
54
55
56
57
58
59

60
61
62
63

64
65
66
67
68
69
70
52
53
54
55
56
57
58

59
60
61
62

63
64
65
66
67
68
69
70







-
+



-
+







.SH "TAB OPTIONS"
The following options may be specified for individual notebook panes:
.OP \-state state State
Either \fBnormal\fR, \fBdisabled\fR or \fBhidden\fR.
If \fBdisabled\fR, then the tab is not selectable.
If \fBhidden\fR, then the tab is not shown.
.OP \-sticky sticky Sticky
Specifies how the slave window is positioned within the pane area.
Specifies how the content window is positioned within the pane area.
Value is a string containing zero or more of the characters
\fBn, s, e,\fR or \fBw\fR.
Each letter refers to a side (north, south, east, or west)
that the slave window will
that the content window will
.QW stick
to, as per the \fBgrid\fR geometry manager.
.OP \-padding padding Padding
Specifies the amount of extra space to add between the notebook and this pane.
Syntax is the same as for the widget \fB\-padding\fR option.
.OP \-text text Text
Specifies a string to be displayed in the tab.
82
83
84
85
86
87
88
89

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






105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117






118
119
120
121
122
123
124







-
+















+
+
+
+
+
+







-
-
-
-
-
-







if \fBttk::notebook::enableTraversal\fR is called.
.SH "TAB IDENTIFIERS"
The \fItabid\fR argument to the following commands may take
any of the following forms:
.IP \(bu
An integer between zero and the number of tabs;
.IP \(bu
The name of a slave window;
The name of a content window;
.IP \(bu
A positional specification of the form
.QW @\fIx\fR,\fIy\fR ,
which identifies the tab
.IP \(bu
The literal string
.QW \fBcurrent\fR ,
which identifies the currently-selected tab; or:
.IP \(bu
The literal string
.QW \fBend\fR ,
which returns the number of tabs
(only valid for
.QW "\fIpathname \fBindex\fR" ).
.SH "WIDGET COMMAND"
.PP
In addition to the standard
\fBcget\fR, \fBconfigure\fR, \fBinstate\fR,
\fBstate\fR and \fBstyle\fR
commands (see \fBttk::widget\fR),
notebook widgets support the following additional commands:
.TP
\fIpathname \fBadd \fIwindow\fR ?\fIoptions...\fR?
Adds a new tab to the notebook.
See \fBTAB OPTIONS\fR for the list of available \fIoptions\fR.
If \fIwindow\fR is currently managed by the notebook but hidden,
it is restored to its previous position.
.TP
\fIpathname \fBconfigure\fR ?\fIoptions\fR?
See \fIttk::widget(n)\fR.
.TP
\fIpathname \fBcget \fIoption\fR
See \fIttk::widget(n)\fR.
.TP
\fIpathname \fBforget \fItabid\fR
Removes the tab specified by \fItabid\fR,
unmaps and unmanages the associated window.
.TP
\fIpathname \fBhide \fItabid\fR
Hides the tab specified by \fItabid\fR.
The tab will not be displayed, but the associated window
147
148
149
150
151
152
153
154
155
156
157
158
159

160
161
162
163
164
165
166
167
168
169
170
171
172
173
147
148
149
150
151
152
153



154
155

156
157
158
159
160



161
162
163
164
165
166
167







-
-
-


-
+




-
-
-







Inserts a pane at the specified position.
\fIpos\fR is either the string \fBend\fR, an integer index,
or the name of a managed subwindow.
If \fIsubwindow\fR is already managed by the notebook,
moves it to the specified position.
See \fBTAB OPTIONS\fR for the list of available options.
.TP
\fIpathname \fBinstate \fIstatespec \fR?\fIscript...\fR?
See \fIttk::widget(n)\fR.
.TP
\fIpathname \fBselect\fR ?\fItabid\fR?
Selects the specified tab.
The associated slave window will be displayed,
The associated content window will be displayed,
and the previously-selected window (if different) is unmapped.
If \fItabid\fR is omitted, returns the widget name of the
currently selected pane.
.TP
\fIpathname \fBstate\fR ?\fIstatespec\fR?
See \fIttk::widget(n)\fR.
.TP
\fIpathname \fBtab \fItabid\fR ?\fI\-option \fR?\fIvalue ...\fR
Query or modify the options of the specific tab.
If no \fI\-option\fR is specified,
returns a dictionary of the tab option values.
If one \fI\-option\fR is specified,
returns the value of that \fIoption\fR.
Otherwise, sets the \fI\-option\fRs to the corresponding \fIvalue\fRs.

Changes to doc/ttk_panedwindow.n.

44
45
46
47
48
49
50


51
52
53




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



53
54
55
56
57
58
59
60
61
62
63







+
+
-
-
-
+
+
+
+







.SH "PANE OPTIONS"
The following options may be specified for each pane:
.OP \-weight weight Weight
An integer specifying the relative stretchability of the pane.
When the paned window is resized, the extra space is added
or subtracted to each pane proportionally to its \fB\-weight\fR.
.SH "WIDGET COMMAND"
.PP
In addition to the standard
Supports the standard \fBconfigure\fR, \fBcget\fR, \fBstate\fR,
and \fBinstate\fR commands; see \fIttk::widget(n)\fR for details.
Additional commands:
\fBcget\fR, \fBconfigure\fR, \fBinstate\fR,
\fBstate\fR and \fBstyle\fR
commands (see \fBttk::widget\fR),
panedwindow widgets support the following additional commands:
.TP
\fIpathname \fBadd \fIsubwindow options...\fR
Adds a new pane to the window.
See \fBPANE OPTIONS\fR for the list of available options.
.TP
\fIpathname \fBforget \fIpane\fR
Removes the specified subpane from the widget.
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
105
106
107
108
109
110
111








112
113
114
115
116
117
118







-
-
-
-
-
-
-
-







Sash positions are further constrained to be between 0
and the total size of the widget.
.\" Full story: "total size" is either the -height (resp -width),
.\" or the actual window height (resp actual window width),
.\" depending on which changed most recently.
Returns the new position of sash number \fIindex\fR.
.\" Full story: new position may be different than the requested position.
.PP
The panedwindow widget also supports the following generic \fBttk::widget\fR
widget subcommands (see \fIttk::widget(n)\fR for details):
.DS
.ta 5.5c 11c
\fBcget\fR	\fBconfigure\fR
\fBinstate\fR	\fBstate\fR
.DE
.SH "VIRTUAL EVENTS"
.PP
The panedwindow widget generates an \fB<<EnteredChild>>\fR virtual event on
LeaveNotify/NotifyInferior events, because Tk does not execute binding scripts
for <Leave> events when the pointer crosses from a parent to a child. The
panedwindow widget needs to know when that happens.
.SH "STYLING OPTIONS"

Changes to doc/ttk_progressbar.n.

62
63
64
65
66
67
68
69
70

71
72
73

74
75
76

77
78

79
80
81

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
62
63
64
65
66
67
68


69



70



71


72



73
74
75
76
77
78
79
80



81
82
83
84
85
86
87







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







-
-
-







.OP \-variable variable Variable
The name of a global Tcl variable which is linked to the \fB\-value\fR.
If specified to an existing variable, the \fB\-value\fR of the progress bar is
automatically set to the value of the variable whenever
the latter is modified.
.SH "WIDGET COMMAND"
.PP
.TP
\fIpathName \fBcget \fIoption\fR
In addition to the standard
Returns the current value of the specified \fIoption\fR; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
\fBcget\fR, \fBconfigure\fR, \fBidentify element\fR, \fBinstate\fR,
Modify or query widget options; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBidentify \fIx y\fR
\fBstate\fR and \fBstyle\fR
Returns the name of the element at position \fIx\fR, \fIy\fR.
See \fIttk::widget(n)\fR.
commands (see \fBttk::widget\fR),
.TP
\fIpathName \fBinstate \fIstatespec\fR ?\fIscript\fR?
Test the widget state; see \fIttk::widget(n)\fR.
progressbar widgets support the following additional commands:
.TP
\fIpathName \fBstart\fR ?\fIinterval\fR?
Begin autoincrement mode:
schedules a recurring timer event that calls \fBstep\fR
every \fIinterval\fR milliseconds.
If omitted, \fIinterval\fR defaults to 50 milliseconds (20 steps/second).
.TP
\fIpathName \fBstate\fR ?\fIstateSpec\fR?
Modify or query the widget state; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBstep\fR ?\fIamount\fR?
Increments the \fB\-value\fR by \fIamount\fR.
\fIamount\fR defaults to 1.0 if omitted.
.TP
\fIpathName \fBstop\fR
Stop autoincrement mode:
cancels any recurring timer event initiated by \fIpathName \fBstart\fR.

Changes to doc/ttk_radiobutton.n.

33
34
35
36
37
38
39
40
41




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


40
41
42
43

44
45
46
47
48
49
50







-
-
+
+
+
+
-







when the widget is selected.
.OP \-variable variable Variable
The name of a global variable whose value is linked to the widget.
Default value is \fB::selectedButton\fR.
.SH "WIDGET COMMAND"
.PP
In addition to the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR
commands, radiobuttons support the following additional
\fBcget\fR, \fBconfigure\fR, \fBidentify element\fR, \fBinstate\fR,
\fBstate\fR and \fBstyle\fR
commands (see \fBttk::widget\fR),
radiobutton widgets support the following additional commands:
widget commands:
.TP
\fIpathname\fB invoke\fR
Sets the \fB\-variable\fR to the \fB\-value\fR, selects the widget,
and evaluates the associated \fB\-command\fR.
Returns the result of the \fB\-command\fR, or the empty
string if no \fB\-command\fR is specified.
.\" Missing: select, deselect.  Useful?

Changes to doc/ttk_scale.n.

47
48
49
50
51
52
53
54
55

56
57
58



59
60
61
62

63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
47
48
49
50
51
52
53


54



55
56
57




58
59
60

61
62
63
64








65

66
67
68
69




70
71
72
73

74
75
76
77
78
79
80







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


-




-
-
-
-
-
-
-
-

-




-
-
-
-




-







.OP \-variable variable Variable
Specifies the name of a global variable to link to the scale. Whenever the
value of the variable changes, the scale will update to reflect this value.
Whenever the scale is manipulated interactively, the variable will be modified
to reflect the scale's new value.
.SH "WIDGET COMMAND"
.PP
.TP
\fIpathName \fBcget \fIoption\fR
In addition to the standard
.
Returns the current value of the specified \fIoption\fR; see
\fIttk::widget(n)\fR.
\fBcget\fR, \fBconfigure\fR, \fBidentify element\fR, \fBinstate\fR,
\fBstate\fR and \fBstyle\fR
commands (see \fBttk::widget\fR),
.TP
\fIpathName \fBconfigure \fR?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Modify or query widget options; see \fIttk::widget(n)\fR.
scale widgets support the following additional commands:
.TP
\fIpathName \fBget \fR?\fIx y\fR?
.
Get the current value of the \fB\-value\fR option, or the value corresponding
to the coordinates \fIx,y\fR if they are specified. \fIX\fR and \fIy\fR are
pixel coordinates relative to the scale widget origin.
.TP
\fIpathName \fBidentify \fIx y\fR
Returns the name of the element at position \fIx\fR, \fIy\fR.
See \fIttk::widget(n)\fR.
.TP
\fIpathName \fBinstate \fIstatespec\fR ?\fIscript\fR?
.
Test the widget state; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBset \fIvalue\fR
.
Set the value of the widget (i.e. the \fB\-value\fR option) to \fIvalue\fR.
The value will be clipped to the range given by the \fB\-from\fR and
\fB\-to\fR options. Note that setting the linked variable (i.e. the variable
named in the \fB\-variable\fR option) does not cause such clipping.
.TP
\fIpathName \fBstate\fR ?\fIstateSpec\fR?
.
Modify or query the widget state; see \fIttk::widget(n)\fR.
.SH "INTERNAL COMMANDS"
.PP
.TP
\fIpathName \fBcoords \fR?\fIvalue\fR?
.
Get the coordinates corresponding to \fIvalue\fR, or the coordinates
corresponding to the current value of the \fB\-value\fR option if \fIvalue\fR
is omitted.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::scale\fP is \fBTScale\fP.
.PP

Changes to doc/ttk_scrollbar.n.

43
44
45
46
47
48
49
50
51

52
53
54
55




56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
43
44
45
46
47
48
49


50




51
52
53
54
55
56
57
58
59







60
61
62
63
64



65
66
67
68
69
70
71







-
-
+
-
-
-
-
+
+
+
+





-
-
-
-
-
-
-





-
-
-







or \fByview\fR (for vertical scrollbars).
.RE
.OP \-orient orient Orient
One of \fBhorizontal\fR or \fBvertical\fR.
Specifies the orientation of the scrollbar.
.SH "WIDGET COMMAND"
.PP
.TP
\fIpathName \fBcget \fIoption\fR
In addition to the standard
Returns the current value of the specified \fIoption\fR; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
Modify or query widget options; see \fIttk::widget(n)\fR.
\fBcget\fR, \fBconfigure\fR, \fBidentify element\fR, \fBinstate\fR,
\fBstate\fR and \fBstyle\fR
commands (see \fBttk::widget\fR),
scrollbar widgets support the following additional commands:
.TP
\fIpathName \fBget\fR
Returns the scrollbar settings in the form of a list whose
elements are the arguments to the most recent \fBset\fR widget command.
.TP
\fIpathName \fBidentify \fIx y\fR
Returns the name of the element at position \fIx\fR, \fIy\fR.
See \fIttk::widget(n)\fR.
.TP
\fIpathName \fBinstate \fIstatespec\fR ?\fIscript\fR?
Test the widget state; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBset \fIfirst last\fR
This command is normally invoked by the scrollbar's associated widget
from an \fB\-xscrollcommand\fR or \fB\-yscrollcommand\fR callback.
Specifies the visible range to be displayed.
\fIfirst\fR and \fIlast\fR are real fractions between 0 and 1.
.TP
\fIpathName \fBstate\fR ?\fIstateSpec\fR?
Modify or query the widget state; see \fIttk::widget(n)\fR.
.SH "INTERNAL COMMANDS"
.PP
The following widget commands are used internally
by the \fBTScrollbar\fP widget class bindings.
.TP
\fIpathName \fBdelta \fIdeltaX deltaY\fR
Returns a real number indicating the fractional change in

Changes to doc/ttk_separator.n.

22
23
24
25
26
27
28
29
30
31




32
33
34
35
36
37
38
22
23
24
25
26
27
28



29
30
31
32
33
34
35
36
37
38
39







-
-
-
+
+
+
+







.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-orient orient Orient
One of \fBhorizontal\fR or \fBvertical\fR.
Specifies the orientation of the separator.
.SH "WIDGET COMMAND"
.PP
Separator widgets support the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR
methods.  No other widget methods are used.
Separator widgets support the standard commands
\fBcget\fR, \fBconfigure\fR, \fBidentify element\fR, \fBinstate\fR,
\fBstate\fR and \fBstyle\fR
(see \fBttk::widget\fR).
.PP
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::separator\fP is \fBTSeparator\fP.
.PP
\fBTSeparator\fP styling options configurable with \fBttk::style\fP
are:

Changes to doc/ttk_sizegrip.n.

19
20
21
22
23
24
25
26
27
28




29
30
31
32
33
34
35
19
20
21
22
23
24
25



26
27
28
29
30
31
32
33
34
35
36







-
-
-
+
+
+
+







by pressing and dragging the grip.
.SO ttk_widget
\-class	\-cursor
\-style	\-takefocus
.SE
.SH "WIDGET COMMAND"
.PP
Sizegrip widgets support the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR
methods.  No other widget methods are used.
Sizegrip widgets support the standard commands
\fBcget\fR, \fBconfigure\fR, \fBidentify element\fR, \fBinstate\fR,
\fBstate\fR and \fBstyle\fR
(see \fBttk::widget\fR).
.SH "PLATFORM-SPECIFIC NOTES"
.PP
On Mac OSX, 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

Changes to doc/ttk_spinbox.n.

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







-
+







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
\-takefocus	\-xscrollcommand	\-placeholder	\-placeholderforeground
.SE
.SO ttk_entry
\-validate	\-validatecommand
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-command command Command
Specifies a Tcl command to be invoked whenever a spinbutton is invoked.
103
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
119
120
121
122
123
124
125







+
+
+
+



+
+







.br
\fB\-darkcolor\fP \fIcolor\fP
.br
\fB\-fieldbackground\fP \fIcolor\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-insertcolor\fP \fIcolor\fP
.br
\fB\-insertwidth\fP \fIamount\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.br
\fB\-placeholderforeground\fP \fIcolor\fP
.br
\fB\-selectbackground\fP \fIcolor\fP
.br
\fB\-selectforeground\fP \fIcolor\fP
.PP
Some options are only available for specific themes.
.PP

Changes to doc/ttk_style.n.

23
24
25
26
27
28
29



30
31
32
33
34
35
36
37
38

39
40
41
42
43
44


45
46

47
48
49

50
51
52
53
54

55
56
57
58

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

































73
74
75
76
77
78
79
80



81
82
83
84
85
86
87
88



89
90
91
92
93

94
95
96
97
98
99
100


101












102
103
104
105



106


107
108


109
110
111
112
113






114
115
116
117
118
119
120
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38



39






40
41


42



43



44

45




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


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

149
150
151
152
153
154





155
156
157
158
159
160
161
162
163
164
165
166
167







+
+
+






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

-
+
-
-
-
-
+














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








+
+
+






-
-
+
+
+





+







+
+

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




+
+
+
-
+
+


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







and how they are arranged, along with dynamic and default
settings for element options.
By default, the style name is the same as the widget's class;
this may be overridden by the \fB\-style\fR option.
.PP
A \fItheme\fR is a collection of elements and styles
which controls the overall look and feel of an application.
The
.QW .
style is the theme root style on which derived styles are based.
.SH DESCRIPTION
.PP
The \fBttk::style\fR command takes the following arguments:
.TP
\fBttk::style configure \fIstyle\fR ?\fI\-option\fR ?\fIvalue option value...\fR? ?
Sets the default value of the specified option(s) in \fIstyle\fR.
.TP
\fBttk::style map \fIstyle\fR ?\fI\-option\fB { \fIstatespec value...\fB }\fR?
Sets dynamic values of the specified option(s) in \fIstyle\fR.
If \fIstyle\fR does not exist, it is created.
Each \fIstatespec / value\fR pair is examined in order;
the value corresponding to the first matching \fIstatespec\fR
is used.
.TP
\fBttk::style lookup \fIstyle\fR \fI\-option \fR?\fIstate \fR?\fIdefault\fR??
Returns the value specified for \fI\-option\fR in style \fIstyle\fR
If only \fIstyle\fR and \fI-option\fR are specified, get the default value
for option \fI-option\fR of style \fIstyle\fR.
in state \fIstate\fR, using the standard lookup rules for element options.
\fIstate\fR is a list of state names; if omitted,
If only \fIstyle\fR is specified, get the default value for all options
it defaults to all bits off (the
.QW normal
state).
of style \fIstyle\fR.
If the \fIdefault\fR argument is present, it is used as a fallback
value in case no specification for \fI\-option\fR is found.
.\" Otherwise -- signal error? return empty string? Leave unspecified for now.
.TP
\fBttk::style layout \fIstyle\fR ?\fIlayoutSpec\fR?
\fBttk::style element\fR \fIargs\fR
Define the widget layout for style \fIstyle\fR.
See \fBLAYOUTS\fR below for the format of \fIlayoutSpec\fR.
If \fIlayoutSpec\fR is omitted, return the layout specification
for style \fIstyle\fR.
.RS
.TP
\fBttk::style element create\fR \fIelementName\fR \fItype\fR ?\fIargs...\fR?
Creates a new element in the current theme of type \fItype\fR.
The only cross-platform built-in element type is \fIimage\fR
(see \fBttk_image\fR(n)) but themes may define other element types
(see \fBTtk_RegisterElementFactory\fR). On suitable versions of Windows
an element factory is registered to create Windows theme elements
(see \fBttk_vsapi\fR(n)).
.TP
\fBttk::style element names\fR
Returns the list of elements defined in the current theme.
.TP
\fBttk::style element options \fIelement\fR
Returns the list of \fIelement\fR's options.
.RE
.TP
\fBttk::style layout \fIstyle\fR ?\fIlayoutSpec\fR?
Define the widget layout for style \fIstyle\fR.
See \fBLAYOUTS\fR below for the format of \fIlayoutSpec\fR.
If \fIlayoutSpec\fR is omitted, return the layout specification
for style \fIstyle\fR.
.TP
\fBttk::style lookup \fIstyle\fR \fI\-option \fR?\fIstate \fR?\fIdefault\fR??
Returns the value specified for \fI\-option\fR in style \fIstyle\fR
in state \fIstate\fR, using the standard lookup rules for element options.
\fIstate\fR is a list of state names; if omitted,
it defaults to all bits off (the
.QW normal
state).
If the \fIdefault\fR argument is present, it is used as a fallback
value in case no specification for \fI\-option\fR is found.
.\" Otherwise -- signal error? return empty string? Leave unspecified for now.
If \fIstyle\fR does not exist, it is created.
.TP
\fBttk::style map \fIstyle\fR ?\fI\-option\fB { \fIstatespec value...\fB }\fR?
Sets dynamic (state dependent) values of the specified option(s) in \fIstyle\fR.
Each \fIstatespec / value\fR pair is examined in order;
the value corresponding to the first matching \fIstatespec\fR
is used.
If \fIstyle\fR does not exist, it is created.
If only \fIstyle\fR and \fI-option\fR are specified, get the dynamic values
for option \fI-option\fR of style \fIstyle\fR.
If only \fIstyle\fR is specified, get the dynamic values for all options
of style \fIstyle\fR.
.TP
\fBttk::style theme\fR \fIargs\fR
.RS
.TP
\fBttk::style theme create\fR \fIthemeName\fR ?\fB\-parent \fIbasedon\fR? ?\fB\-settings \fIscript...\fR ?
Creates a new theme.  It is an error if \fIthemeName\fR already exists.
If \fB\-parent\fR is specified, the new theme will inherit
styles, elements, and layouts from the parent theme \fIbasedon\fR.
If \fB\-settings\fR is present, \fIscript\fR is evaluated in the
context of the new theme as per \fBttk::style theme settings\fR.
.TP
\fBttk::style theme names\fR
Returns a list of all known themes.
.TP
\fBttk::style theme settings \fIthemeName\fR \fIscript\fR
Temporarily sets the current theme to \fIthemeName\fR,
evaluate \fIscript\fR, then restore the previous theme.
Typically \fIscript\fR simply defines styles and elements,
though arbitrary Tcl code may appear.
.TP
\fBttk::style theme names\fR
Returns a list of all known themes.
\fBttk::style theme styles\fR ?\fIthemeName\fR?
Returns a list of all styles in \fIthemeName\fR. If \fIthemeName\fR
is omitted, the current theme is used.
.TP
\fBttk::style theme use\fR ?\fIthemeName\fR?
Without an argument the result is the name of the current theme.
Otherwise this command sets the current theme to \fIthemeName\fR,
and refreshes all widgets.
.RE
.SH LAYOUTS
.PP
A \fIlayout\fR specifies a list of elements, each followed
by one or more options specifying how to arrange the element.
The layout mechanism uses a simplified version of the \fBpack\fR
geometry manager: given an initial cavity,
each element is allocated a parcel.
Then the parcel actually used by the element is adjusted within
the allocated parcel.
Valid options are:
.\" -border should remain undocumented for now (dubious usefulness)
.\" .TP
.\" \fB\-border\fR \fIboolean\fR
.\" Specifies whether the element is drawn after its children. Defaults to 0.
.TP
\fB\-children { \fIsublayout...\fB }\fR
Specifies a list of elements to place inside the element.
.TP
\fB\-expand\fR \fIboolean\fR
Specifies whether the allocated parcel is the entire cavity. If so,
simultaneous specification of \fB\-side\fR is ignored.
Defaults to 0.
.TP
\fB\-side \fIside\fR
Specifies which side of the cavity to place the element;
one of \fBleft\fR, \fBright\fR, \fBtop\fR, or \fBbottom\fR.
For instance, \fB\-side top\fR allocates the parcel along the top of
the cavity having width and height respectively the width of the cavity
and the height of the element.
If omitted, the element occupies the entire cavity.
If omitted, the allocated parcel is the entire cavity (same effect
as \fB\-expand\fR 1).
.TP
\fB\-sticky\fR \fB[\fInswe\fB]\fR
Specifies the actual parcel position and size inside the allocated parcel.
If specified as an empty string then the actual parcel is centered in
Specifies where the element is placed inside its allocated parcel.
.TP
\fB\-children { \fIsublayout... \fB}\fR
Specifies a list of elements to place inside the element.
.\" Also: -border, -unit, -expand: may go away.
the allocated parcel. Default is \fBnswe\fR.
.\" -unit should remain undocumented for now (dubious usefulness)
.\" .TP
.\" \fB\-unit\fR \fIboolean\fR
.\" Specifies whether the element propagates its state to its children.
.\" Defaults to 0.
.PP
For example:
.CS
ttk::style layout Horizontal.TScrollbar {
    Scrollbar.trough \-children {
        Scrollbar.leftarrow \-side left
        Scrollbar.rightarrow \-side right

Changes to doc/ttk_treeview.n.

88
89
90
91
92
93
94





95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109



110
111
112
113
114
115
116







+
+
+
+
+










-
-
-







The default is \fBtree headings\fR, i.e., show all elements.
.PP
\fBNOTE:\fR Column #0 always refers to the tree column,
even if \fB\-show tree\fR is not specified.
.RE
.SH "WIDGET COMMAND"
.PP
In addition to the standard
\fBcget\fR, \fBconfigure\fR, \fBinstate\fR,
\fBstate\fR, \fBstyle\fR, \fBxview\fR and \fByview\fR
commands (see \fBttk::widget\fR),
treeview widgets support the following additional commands:
.TP
\fIpathname \fBbbox \fIitem\fR ?\fIcolumn\fR?
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.
.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.
.RS
.PP
If \fInewchildren\fR is specified, replaces \fIitem\fR's child list
with \fInewchildren\fR.
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
158
159
160
161
162
163
164



165
166
167
168
169
170
171







-
-
-







column width may be changed by Tk in order to honor \fB\-stretch\fR
and/or \fB\-minwidth\fR, or when the widget is resized or the user drags a
column separator.
.PP
Use \fIpathname column #0\fR to configure the tree column.
.RE
.TP
\fIpathname \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
Modify or query widget options; see \fIttk::widget(n)\fR.
.TP
\fIpathname \fBdelete \fIitemList\fR
Deletes each of the items in \fIitemList\fR and all of their descendants.
The root item may not be deleted.
See also: \fBdetach\fR.
.TP
\fIpathname \fBdetach \fIitemList\fR
Unlinks all of the specified items in \fIitemList\fR from the tree.
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
267
268
269
270
271
272
273



274
275
276
277
278
279
280







-
-
-







.RS
.PP
\fIpathname \fBinsert\fR returns the item identifier of the
newly created item.
See \fBITEM OPTIONS\fR for the list of available options.
.RE
.TP
\fIpathname \fBinstate \fIstatespec\fR ?\fIscript\fR?
Test the widget state; see \fIttk::widget(n)\fR.
.TP
\fIpathname \fBitem \fIitem\fR ?\fI\-option \fR?\fIvalue \-option value...\fR?
Query or modify the options for the specified \fIitem\fR.
If no \fI\-option\fR is specified,
returns a dictionary of option/value pairs.
If a single \fI\-option\fR is specified,
returns the value of that option.
Otherwise, the item's options are updated with the specified values.
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
330
331
332
333
334
335
336



337
338
339
340
341
342
343







-
-
-







With one argument, returns a dictionary of column/value pairs
for the specified \fIitem\fR.
With two arguments, returns the current value of the specified \fIcolumn\fR.
With three arguments, sets the value of column \fIcolumn\fR
in item \fIitem\fR to the specified \fIvalue\fR.
See also \fBCOLUMN IDENTIFIERS\fR.
.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.
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
387
388
389
390
391
392
393







394
395
396
397
398
399
400







-
-
-
-
-
-
-







.TP
\fIpathName \fBtag remove \fItag\fR ?\fIitems\fR?
Removes the specified \fItag\fR from each of the listed \fIitems\fR.
If \fIitems\fR is omitted, removes \fItag\fR from each item in the tree.
If \fItag\fR is not present for a particular item,
then the \fB\-tags\fR for that item are unchanged.
.RE
.PP
The treeview widget also supports the following generic \fBttk::widget\fR
widget subcommands (see \fIttk::widget(n)\fR for details):
.DS
.ta 5.5c 11c
\fBxview\fR	\fByview\fR
.DE
.SH "ITEM OPTIONS"
.PP
The following item options may be specified for items
in the \fBinsert\fR and \fBitem\fR widget commands.
.OP \-text text Text
The textual label to display for the item.
.OP \-image image Image

Changes to doc/ttk_widget.n.

148
149
150
151
152
153
154
155

156
157
158
159

160
161



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202


203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230



231
232
233
234
235
236
237
148
149
150
151
152
153
154

155
156
157
158

159


160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176

177
178
179
180

181
182
183
184
185
186
187
188
189
190
191
192
193
194
195

196
197
198
199

200
201
202
203

204
205
206
207
208
209
210
211
212

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







-
+



-
+
-
-
+
+
+














-




-















-




-
+
+


-









-















+
+
+







.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 option is supported by entry, spinbox and combobox:
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 and \fB\-justify\fR options. The foreground
the values of the \fB\-font\fR, \fB\-justify\fR and
color of the placeholder text can be changed using the
\fB\-placeholderforeground\fR style option.
\fB\-placeholderforeground\fR options.
.OP \-placeholderforeground placeHolderForeground PlaceHolderForeground
Specifies the foreground color of the placeholder text.
.SH "COMPATIBILITY OPTIONS"
This option is only available for themed widgets that have
.QW corresponding
traditional Tk widgets.
.OP \-state state State
May be set to \fBnormal\fR or \fBdisabled\fR
to control the \fBdisabled\fR state bit.
This is a write-only option:
setting it changes the widget state,
but the \fBstate\fR widget command
does not affect the \fB\-state\fR option.
.SH COMMANDS
.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If one or more \fIoption\-value\fR pairs are specified,
then the command modifies the given widget option(s)
to have the given value(s);
in this case the command returns an empty string.
If \fIoption\fR is specified with no \fIvalue\fR,
then the command returns a list describing the named option:
the elements of the list are the
option name, database name, database class, default value,
and current value.
.\" Note: Ttk widgets don't use TK_OPTION_SYNONYM.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR.
.TP
\fIpathName \fBidentify element \fIx y\fR
.
Returns the name of the element under the point given
by \fIx\fR and \fIy\fR, or an empty string if the point does
not lie within any element.
\fIx\fR and \fIy\fR are pixel coordinates relative to the widget.
Some widgets accept other \fBidentify\fR subcommands.
Some widgets accept other \fBidentify\fR subcommands described
in these widgets documentation.
.TP
\fIpathName \fBinstate \fIstatespec\fR ?\fIscript\fR?
.
Test the widget's state.
If \fIscript\fR is not specified, returns 1 if
the widget state matches \fIstatespec\fR and 0 otherwise.
If \fIscript\fR is specified, equivalent to
.CS
if {[\fIpathName\fR instate \fIstateSpec\fR]} \fIscript\fR
.CE
.TP
\fIpathName \fBstate\fR ?\fIstateSpec\fR?
.
Modify or inquire widget state.
If \fIstateSpec\fR is present, sets the widget state:
for each flag in \fIstateSpec\fR, sets the corresponding flag
or clears it if prefixed by an exclamation point.
.RS
Returns a new state spec indicating which flags were changed:
.CS
set changes [\fIpathName \fRstate \fIspec\fR]
\fIpathName \fRstate $changes
.CE
will restore \fIpathName\fR to the original state.
If \fIstateSpec\fR is not specified,
returns a list of the currently-enabled state flags.
.RE
.TP
\fIpathName \fBstyle\fR
Return the style used by the widget.
.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
252
253
254
255
256
257
258
259


260
261
262
263
264
265
266
252
253
254
255
256
257
258

259
260
261
262
263
264
265
266
267







-
+
+







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.
\fINumber\fR must be an integer or a float, but if it is a float then
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR.
'\" or an abbreviation of one of these, but we don't document that.
If \fIwhat\fR is
\fBpages\fR then the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then characters farther to the left
become visible;  if it is positive then characters farther to the right
become visible.

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 arg ...\fR?
\fBwinfo\fR \fIoption \fR?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
The \fBwinfo\fR command is used to retrieve information about windows
managed by Tk.  It can take any of a number of different forms,
depending on the \fIoption\fR argument.  The legal forms are:
.TP

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 arg ...\fR?
\fBwish\fR ?\fB\-encoding \fIname\fR? ?\fIfileName arg ...\fR?
.SH OPTIONS
.IP "\fB\-encoding \fIname\fR" 20
Specifies the encoding of the text stored in \fIfileName\fR.
This option is only recognized prior to the \fIfileName\fR argument.
.IP "\fB\-colormap \fInew\fR" 20
Specifies that the window should have a new private colormap instead of
using the default colormap for the screen.

Changes to doc/wm.n.

704
705
706
707
708
709
710
711

712
713

714
715
716


717
718
719

720
721
722


723
724
725
726
727
728
729
704
705
706
707
708
709
710

711
712

713
714


715
716
717
718

719
720


721
722
723
724
725
726
727
728
729







-
+

-
+

-
-
+
+


-
+

-
-
+
+







If \fIstring\fR is specified, then it will be passed to the window
manager for use as the title for \fIwindow\fR (the window manager
should display this string in \fIwindow\fR's title bar).  In this
case the command returns an empty string.  If \fIstring\fR is not
specified then the command returns the current title for the
\fIwindow\fR.  The title for a window defaults to its name.
.TP
\fBwm transient \fIwindow\fR ?\fImaster\fR?
\fBwm transient \fIwindow\fR ?\fIcontainer\fR?
.
If \fImaster\fR is specified, then the window manager is informed that
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 \fImaster\fR (where \fImaster\fR is the path name for a
top-level window).  If \fImaster\fR is specified as an empty string
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
master, or an empty string if \fIwindow\fR is not currently a
container, or an empty string if \fIwindow\fR is not currently a
transient window.  A transient window will mirror state changes in the
master and inherit the state of the master when initially mapped. The
directed graph with an edge from each transient to its master must be
container and inherit the state of the container when initially mapped. The
directed graph with an edge from each transient to its container must be
acyclic.  In particular, it is an error to attempt to make a window a
transient of itself.  The window manager may also decorate a transient
window differently, removing some features normally present (e.g.,
minimize and maximize buttons) though this is entirely at the
discretion of the window manager.
.TP
\fBwm withdraw \fIwindow\fR

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69



70
71
72
73
74

75





76
77
78
79
80
81
82
16
17
18
19
20
21
22

23




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



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66



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







-

-
-
-
-

















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











-
-
-







+
+
+





+

+
+
+
+
+







{ "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 },
{ "Next", 0xFF56 },
{ "Page_Down", 0xFF56 },
{ "End", 0xFF57 },
{ "Begin", 0xFF58 },
{ "Win_L", 0xFF5B },
{ "Win_R", 0xFF5C },
{ "App", 0xFF5D },
{ "Select", 0xFF60 },
{ "Print", 0xFF61 },
{ "Execute", 0xFF62 },
{ "Insert", 0xFF63 },
{ "Undo", 0xFF65 },
{ "Redo", 0xFF66 },
{ "Menu", 0xFF67 },
#ifndef TK_NO_DEPRECATED
{ "App", 0xFF67 },
#endif
{ "Find", 0xFF68 },
{ "Cancel", 0xFF69 },
{ "Help", 0xFF6A },
{ "Break", 0xFF6B },
{ "Mode_switch", 0xFF7E },
#ifndef TK_NO_DEPRECATED
{ "script_switch", 0xFF7E },
{ "kana_switch", 0xFF7E },
{ "Arabic_switch", 0xFF7E },
{ "Greek_switch", 0xFF7E },
{ "Hebrew_switch", 0xFF7E },
#endif
{ "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
103
104
105
106
107
108
109

110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133







-
















+







{ "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 },
178
179
180
181
182
183
184



185



186
187











188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206



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




223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242







+
+
+

+
+
+


+
+
+
+
+
+
+
+
+
+
+





-
-
-
-










+
+
+







{ "Caps_Lock", 0xFFE5 },
{ "Shift_Lock", 0xFFE6 },
{ "Meta_L", 0xFFE7 },
{ "Meta_R", 0xFFE8 },
{ "Alt_L", 0xFFE9 },
{ "Alt_R", 0xFFEA },
{ "Super_L", 0xFFEB },
#ifndef TK_NO_DEPRECATED
{ "Win_L", 0xFFEB },
#endif
{ "Super_R", 0xFFEC },
#ifndef TK_NO_DEPRECATED
{ "Win_R", 0xFFEC },
#endif
{ "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
285
286
287
288
289
290
291




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











331
332
333
334
335
336
337







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













+
+
+
+
+
+
+
+
+
+





-
-
-
-
-
-
-
-
-
-
-







{ "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 },
{ "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_small_schwa", 0xFE8A },
{ "dead_capital_schwa", 0xFE8B },
{ "dead_greek", 0xFE8C },
{ "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 },
{ "AccessX_Enable", 0xFE70 },
{ "AccessX_Feedback_Enable", 0xFE71 },
{ "RepeatKeys_Enable", 0xFE72 },
{ "SlowKeys_Enable", 0xFE73 },
{ "BounceKeys_Enable", 0xFE74 },
{ "StickyKeys_Enable", 0xFE75 },
{ "MouseKeys_Enable", 0xFE76 },
{ "MouseKeys_Accel_Enable", 0xFE77 },
{ "Overlay1_Enable", 0xFE78 },
{ "Overlay2_Enable", 0xFE79 },
{ "AudibleBell_Enable", 0xFE7A },
{ "Pointer_Left", 0xFEE0 },
{ "Pointer_Right", 0xFEE1 },
{ "Pointer_Up", 0xFEE2 },
{ "Pointer_Down", 0xFEE3 },
{ "Pointer_UpLeft", 0xFEE4 },
{ "Pointer_UpRight", 0xFEE5 },
{ "Pointer_DownLeft", 0xFEE6 },
314
315
316
317
318
319
320
321
322
323
324
325
326

327
328
329
330
331
332
333
334
335
336
337
338
349
350
351
352
353
354
355

356
357
358
359

360





361
362
363
364
365
366
367







-




-
+
-
-
-
-
-







{ "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 },
356
357
358
359
360
361
362

363

364
365
366

367
368
369
370
371
372
373
374
375

376

377
378
379
380
381
382
383
384
385
386
387
388
389

390
391

392

393

394
395
396
397
398
399
400
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438







+

+



+









+

+













+


+

+

+







{ "3270_ChangeScreen", 0xFD19 },
{ "3270_DeleteWord", 0xFD1A },
{ "3270_ExSelect", 0xFD1B },
{ "3270_CursorSelect", 0xFD1C },
{ "3270_PrintScreen", 0xFD1D },
{ "3270_Enter", 0xFD1E },
{ "space", 0x20 },
#ifndef TK_NO_DEPRECATED
{ "exclam", 0x21 },
#endif
{ "quotedbl", 0x22 },
{ "numbersign", 0x23 },
{ "dollar", 0x24 },
#ifndef TK_NO_DEPRECATED
{ "percent", 0x25 },
{ "ampersand", 0x26 },
{ "apostrophe", 0x27 },
{ "quoteright", 0x27 },
{ "parenleft", 0x28 },
{ "parenright", 0x29 },
{ "asterisk", 0x2A },
{ "plus", 0x2B },
{ "comma", 0x2C },
#endif
{ "minus", 0x2D },
#ifndef TK_NO_DEPRECATED
{ "period", 0x2E },
{ "slash", 0x2F },
{ "0", 0x30 },
{ "1", 0x31 },
{ "2", 0x32 },
{ "3", 0x33 },
{ "4", 0x34 },
{ "5", 0x35 },
{ "6", 0x36 },
{ "7", 0x37 },
{ "8", 0x38 },
{ "9", 0x39 },
{ "colon", 0x3A },
#endif
{ "semicolon", 0x3B },
{ "less", 0x3C },
#ifndef TK_NO_DEPRECATED
{ "equal", 0x3D },
#endif
{ "greater", 0x3E },
#ifndef TK_NO_DEPRECATED
{ "question", 0x3F },
{ "at", 0x40 },
{ "A", 0x41 },
{ "B", 0x42 },
{ "C", 0x43 },
{ "D", 0x44 },
{ "E", 0x45 },
415
416
417
418
419
420
421

422
423
424

425
426
427
428
429
430
431
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471







+



+







{ "T", 0x54 },
{ "U", 0x55 },
{ "V", 0x56 },
{ "W", 0x57 },
{ "X", 0x58 },
{ "Y", 0x59 },
{ "Z", 0x5A },
#endif
{ "bracketleft", 0x5B },
{ "backslash", 0x5C },
{ "bracketright", 0x5D },
#ifndef TK_NO_DEPRECATED
{ "asciicircum", 0x5E },
{ "underscore", 0x5F },
{ "grave", 0x60 },
{ "quoteleft", 0x60 },
{ "a", 0x61 },
{ "b", 0x62 },
{ "c", 0x63 },
448
449
450
451
452
453
454

455

456

457

458

459

460
461
462
463
464
465
466
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512







+

+

+

+

+

+







{ "t", 0x74 },
{ "u", 0x75 },
{ "v", 0x76 },
{ "w", 0x77 },
{ "x", 0x78 },
{ "y", 0x79 },
{ "z", 0x7A },
#endif
{ "braceleft", 0x7B },
#ifndef TK_NO_DEPRECATED
{ "bar", 0x7C },
#endif
{ "braceright", 0x7D },
#ifndef TK_NO_DEPRECATED
{ "asciitilde", 0x7E },
#endif
{ "nobreakspace", 0xA0 },
#ifndef TK_NO_DEPRECATED
{ "exclamdown", 0xA1 },
{ "cent", 0xA2 },
{ "sterling", 0xA3 },
{ "currency", 0xA4 },
{ "yen", 0xA5 },
{ "brokenbar", 0xA6 },
{ "section", 0xA7 },
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562

563
564
565
566
567
568
569
592
593
594
595
596
597
598



599
600
601
602
603
604
605
606
607
608
609
610
611
612
613







-
-
-







+







{ "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 },
#endif /* TK_NO_DEPRECATED */
{ "Aogonek", 0x1A1 },
{ "breve", 0x1A2 },
{ "Lstroke", 0x1A3 },
{ "Lcaron", 0x1A5 },
{ "Sacute", 0x1A6 },
{ "Scaron", 0x1A9 },
{ "Scedilla", 0x1AA },
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
720
721
722
723
724
725
726


























727
728
729
730
731
732
733







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







{ "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 },
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
802
803
804
805
806
807
808


















809











810
811
812
813
814
815
816







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

-
-
-
-
-
-
-
-
-
-
-







{ "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 },
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
853
854
855
856
857
858
859












































860
861
862
863
864
865
866







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







{ "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
1050
1051
1052
1053
1054
1055
1056

1057

1058
1059
1060
1061
1062
1063
1064
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011







+

+







{ "Cyrillic_CHE", 0x6FE },
{ "Cyrillic_HARDSIGN", 0x6FF },
{ "Greek_ALPHAaccent", 0x7A1 },
{ "Greek_EPSILONaccent", 0x7A2 },
{ "Greek_ETAaccent", 0x7A3 },
{ "Greek_IOTAaccent", 0x7A4 },
{ "Greek_IOTAdieresis", 0x7A5 },
#ifndef TK_NO_DEPRECATED
{ "Greek_IOTAdiaeresis", 0x7A5 },
#endif
{ "Greek_IOTAaccentdiaeresis", 0x7A6 },
{ "Greek_OMICRONaccent", 0x7A7 },
{ "Greek_UPSILONaccent", 0x7A8 },
{ "Greek_UPSILONdieresis", 0x7A9 },
{ "Greek_UPSILONaccentdieresis", 0x7AA },
{ "Greek_OMEGAaccent", 0x7AB },
{ "Greek_accentdieresis", 0x7AE },
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1068
1069
1070
1071
1072
1073
1074

1075
1076
1077
1078
1079
1080
1081







-







{ "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 },
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1305
1306
1307
1308
1309
1310
1311

1312
1313
1314
1315
1316
1317
1318







-







#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
1389
1390
1391
1392
1393
1394
1395
















1396
1397
1398
1399
1400
1401
1402







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







{ "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
1480
1481
1482
1483
1484
1485
1486






















































































































































































































































































































































































































































































































































































































































1487
1488
1489
1490
1491
1492
1493







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







{ "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 },

Changes to generic/nanosvg.h.

29
30
31
32
33
34
35
36

37
38


39
40


41
42
43



44
45
46



47
48
49



50
51



52
53
54
55
56


57
58
59
60
61
62
63
29
30
31
32
33
34
35

36


37
38


39
40



41
42
43



44
45
46



47
48
49


50
51
52
53
54
55


56
57
58
59
60
61
62
63
64







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



-
-
+
+







#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.
/* 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.
 *
 * 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!
 *
 * 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.
 *
 * 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.
 *
 * 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 NanoVG should be one of: 'px', 'pt', 'pc' 'mm', 'cm', or 'in'.
// DPI (dots-per-inch) controls how the unit conversion is done.
 *
 * 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.
 *
 * If you don't know or care about the units stuff, "px" and 96 should get you going.
 */


/* Example Usage:
	// Load
	NSVGImage* image;
	// 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];
81
82
83
84
85
86
87
88
89


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


103
104
105
106
107
108
109
82
83
84
85
86
87
88


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


102
103
104
105
106
107
108
109
110







-
-
+
+











-
-
+
+







#define NANOSVG_realloc realloc
#endif

#ifndef NANOSVG_free
#define NANOSVG_free free
#endif

// float emulation for MS VC6++ compiler
#if (_MSC_VER == 1200)
/* 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 (_MSC_VER == 1400)
/* 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,
156
157
158
159
160
161
162
163
164
165
166
167





168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
















188
189
190
191
192
193
194



195
196
197

198
199
200
201


202
203
204

205
206
207
208
209
210
211

212
213
214
215
216
217
218
219
220

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


235
236
237
238
239
240

241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267

268
269
270
271
272
273
274
275
276
277

278
279
280
281
282
283
284
285
286
287
288
289
290
291
292

293
294
295
296
297

298
299
300

301
302
303
304
305
306
307
308

309
310
311
312
313


314
315
316
317

318
319
320
321
322

323
324
325
326
327
328
329
330

331
332
333

334
335
336
337
338

339
340
341
342
343

344
345
346
347
348
349
350

351
352
353
354

355
356

357
358

359
360
361
362
363
364
365
366
367
368
369
370
371
372
373

374
375
376
377
378
379

380
381
382
383
384
385
386
157
158
159
160
161
162
163





164
165
166
167
168
169
170
171
172
















173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192



193
194
195
196
197

198
199
200


201
202
203
204

205
206
207
208
209
210
211

212
213
214
215
216
217
218
219
220

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


234
235
236
237
238
239
240

241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258





259
260
261
262

263
264
265
266
267
268
269
270
271
272

273
274
275
276
277
278
279
280
281
282
283
284
285
286
287

288
289
290
291
292

293
294
295

296
297
298
299
300
301
302
303

304
305
306
307


308
309
310
311
312

313
314
315
316
317

318
319
320
321
322
323
324
325

326
327
328

329
330
331
332
333

334
335
336
337
338

339
340
341
342
343
344
345

346
347
348
349

350
351

352
353

354
355
356
357
358
359
360
361
362
363
364
365
366
367
368

369
370
371
372
373
374

375
376
377
378
379
380
381
382







-
-
-
-
-
+
+
+
+
+




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




-
-
-
+
+
+


-
+


-
-
+
+


-
+






-
+








-
+












-
-
+
+





-
+

















-
-
-
-
-




-
+









-
+














-
+




-
+


-
+







-
+



-
-
+
+



-
+




-
+







-
+


-
+




-
+




-
+






-
+



-
+

-
+

-
+














-
+





-
+







		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.
	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.
	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.
	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.
/* 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.
/* 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.
/* Deletes list of paths. */
NANOSVG_SCOPE void nsvgDelete(NSVGimage* image);

#ifdef __cplusplus
}
#endif

#endif // NANOSVG_H
#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_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
	#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()
	#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 int nsvg__isnum(char c)
{
	return strchr("0123456789+-.eE", c) != 0;
}

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
/* 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
	/* 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* name;
	char* cbname;
	int start = 0;
	int end = 0;
	char quote;

	// Skip white space after the '<'
	/* Skip white space after the '<' */
	while (*s && nsvg__isspace(*s)) s++;

	// Check if the tag is end tag
	/* Check if the tag is end tag */
	if (*s == '/') {
		s++;
		end = 1;
	} else {
		start = 1;
	}

	// Skip comments, data and preprocessor stuff.
	/* Skip comments, data and preprocessor stuff. */
	if (!*s || *s == '?' || *s == '!')
		return;

	// Get tag name
	name = s;
	/* Get tag name */
	cbname = s;
	while (*s && !nsvg__isspace(*s)) s++;
	if (*s) { *s++ = '\0'; }

	// Get attribs
	/* Get attribs */
	while (!end && *s && nattr < NSVG_XML_MAX_ATTRIBS-3) {
		char* name = NULL;
		char* value = NULL;

		// Skip white space before the attrib name
		/* 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.
		/* Find end of the attrib name. */
		while (*s && !nsvg__isspace(*s) && *s != '=') s++;
		if (*s) { *s++ = '\0'; }
		// Skip until the beginning of the value.
		/* 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.
		/* Store value and find the end of it. */
		value = s;
		while (*s && *s != quote) s++;
		if (*s) { *s++ = '\0'; }

		// Store only well formed attributes
		/* Store only well formed attributes */
		if (name && value) {
			attr[nattr++] = name;
			attr[nattr++] = value;
		}
	}

	// List terminator
	/* List terminator */
	attr[nattr++] = 0;
	attr[nattr++] = 0;

	// Call callbacks.
	/* Call callbacks. */
	if (start && startelCb)
		(*startelCb)(ud, name, attr);
		(*startelCb)(ud, cbname, attr);
	if (end && endelCb)
		(*endelCb)(ud, name);
		(*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
			/* 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.
			/* 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++;
616
617
618
619
620
621
622
623

624
625
626
627
628
629
630


631
632
633
634

635
636
637
638
639
640
641
612
613
614
615
616
617
618

619
620
621
622
623
624


625
626
627
628
629

630
631
632
633
634
635
636
637







-
+





-
-
+
+



-
+







	int 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
	/* 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.
	/* 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.
	/* 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) {
669
670
671
672
673
674
675
676

677
678
679
680
681
682
683
665
666
667
668
669
670
671

672
673
674
675
676
677
678
679







-
+







	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
	/* 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;
791
792
793
794
795
796
797

798
799
800




801
802
803
804
805
806
807
787
788
789
790
791
792
793
794



795
796
797
798
799
800
801
802
803
804
805







+
-
-
-
+
+
+
+







		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);
		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];
}

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







-
+









+
+
-
+
















+




-
+

+

+





-
+
+
+
+
+






-
+



















-
+












-
+







		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_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) {
	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.
	/* 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;
		}
		ref = nsvg__findGradientData(p, ref->ref);
		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.
	/* 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
		/* 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
		/* 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;
	}

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







-
+











-
+
















-
+















-
+


-
+







	shape->miterLimit = attr->miterLimit;
	shape->fillRule = attr->fillRule;
	shape->opacity = attr->opacity;

	shape->paths = p->plist;
	p->plist = NULL;

	// Calculate shape bounds
	/* 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
	/* 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
	/* 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
	/* Set flags */
	shape->flags = ((attr->visible & NSVG_VIS_DISPLAY) && (attr->visible & NSVG_VIS_VISIBLE) ? NSVG_FLAGS_VISIBLE : 0x00);

	// Add to tail
	/* Add to tail */
	if (p->image->shapes == NULL)
		p->image->shapes = shape;
	else
		p->shapesTail->next = shape;
	p->shapesTail = shape;

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







+
+
+
+










-
+



-
+







	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.
	/* 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
	/* 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];
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
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







-
+





-
+






-
+







-
+

-
-
+
+











-
+

-
+

-
-
+
+












-
+



-
+


-
-
+
+














-
+




-
+





-
+


-
+





-
+




















-
+





-
+












-
-
+
+







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.
/* 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 (_MSC_VER == 1200)
#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
	/* Parse optional sign */
	if (*cur == '+') {
		cur++;
	} else if (*cur == '-') {
		sign = -1;
		cur++;
	}

	// Parse integer part
	/* Parse integer part */
	if (nsvg__isdigit(*cur)) {
		// Parse digit sequence
#if (_MSC_VER == 1200)
		/* 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.
	/* Parse fractional part. */
	if (*cur == '.') {
		cur++; // Skip '.'
		cur++; /* Skip '.' */
		if (nsvg__isdigit(*cur)) {
			// Parse digit sequence
#if (_MSC_VER == 1200)
			/* 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.
	/* A valid number should have integer or fractional part. */
	if (!hasIntPart && !hasFracPart)
		return 0.0;

	// Parse optional exponent
	/* Parse optional exponent */
	if (*cur == 'e' || *cur == 'E') {
		int expPart = 0;
		cur++; // skip 'E'
		expPart = strtol(cur, &end, 10); // Parse digit sequence with sign
		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
	/* sign */
	if (*s == '-' || *s == '+') {
		if (i < last) it[i++] = *s;
		s++;
	}
	// integer part
	/* integer part */
	while (*s && nsvg__isdigit(*s)) {
		if (i < last) it[i++] = *s;
		s++;
	}
	if (*s == '.') {
		// decimal point
		/* decimal point */
		if (i < last) it[i++] = *s;
		s++;
		// fraction part
		/* fraction part */
		while (*s && nsvg__isdigit(*s)) {
			if (i < last) it[i++] = *s;
			s++;
		}
	}
	// exponent
	/* 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
	/* 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
		/* 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.
	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);
1526
1527
1528
1529
1530
1531
1532









1533
1534
1535
1536
1537
1538
1539
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559







+
+
+
+
+
+
+
+
+







		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, or start by a dot */
	return (nsvg__isdigit(*s) || *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);
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
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







+




-
+

-
+

-
+

-
+

-
+

-
+




+
+
+
+
+
+








-
+

















-
+











-
+









-
+







-
+

-
+















-
+



-
+








	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)
			str += nsvg__parseMatrix(t, str);
			len = nsvg__parseMatrix(t, str);
		else if (strncmp(str, "translate", 9) == 0)
			str += nsvg__parseTranslate(t, str);
			len = nsvg__parseTranslate(t, str);
		else if (strncmp(str, "scale", 5) == 0)
			str += nsvg__parseScale(t, str);
			len = nsvg__parseScale(t, str);
		else if (strncmp(str, "rotate", 6) == 0)
			str += nsvg__parseRotate(t, str);
			len = nsvg__parseRotate(t, str);
		else if (strncmp(str, "skewX", 5) == 0)
			str += nsvg__parseSkewX(t, str);
			len = nsvg__parseSkewX(t, str);
		else if (strncmp(str, "skewY", 5) == 0)
			str += nsvg__parseSkewY(t, str);
			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(";
	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.
	/* 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.
	/* 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.
	/* 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
	/* Skip white spaces and commas */
	while (*s && (nsvg__isspace(*s) || *s == ',')) s++;
	// Advance until whitespace, comma or end.
	/* 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"
	/* Handle "none" */
	if (str[0] == 'n')
		return 0;

	// Parse dashes
	/* 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)));
	}

1792
1793
1794
1795
1796
1797
1798
1799

1800
1801
1802
1803
1804
1805
1806
1819
1820
1821
1822
1823
1824
1825

1826
1827
1828
1829
1830
1831
1832
1833







-
+







	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
		/* 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;
		}
1884
1885
1886
1887
1888
1889
1890
1891

1892
1893
1894
1895
1896
1897
1898
1911
1912
1913
1914
1915
1916
1917

1918
1919
1920
1921
1922
1923
1924
1925







-
+







	int n;

	str = start;
	while (str < end && *str != ':') ++str;

	val = str;

	// Right Trim
	/* 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;
1909
1910
1911
1912
1913
1914
1915
1916

1917
1918
1919
1920
1921
1922

1923
1924
1925
1926
1927
1928
1929
1936
1937
1938
1939
1940
1941
1942

1943
1944
1945
1946
1947
1948

1949
1950
1951
1952
1953
1954
1955
1956







-
+





-
+








static void nsvg__parseStyle(NSVGparser* p, const char* str)
{
	const char* start;
	const char* end;

	while (*str) {
		// Left Trim
		/* Left Trim */
		while(*str && nsvg__isspace(*str)) ++str;
		start = str;
		while(*str && *str != ';') ++str;
		end = str;

		// Right Trim
		/* Right Trim */
		while (end > start &&  (*end == ';' || nsvg__isspace(*end))) --end;
		++end;

		nsvg__parseNameValue(p, start, end);
		if (*str) ++str;
	}
}
1962
1963
1964
1965
1966
1967
1968



1969
1970

1971
1972
1973
1974
1975
1976
1977
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999

2000
2001
2002
2003
2004
2005
2006
2007







+
+
+

-
+







			return 4;
		case 'c':
		case 'C':
			return 6;
		case 'a':
		case 'A':
			return 7;
		case 'z':
		case 'Z':
			return 0;
	}
	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];
2087
2088
2089
2090
2091
2092
2093
2094

2095
2096
2097
2098
2099
2100
2101
2117
2118
2119
2120
2121
2122
2123

2124
2125
2126
2127
2128
2129
2130
2131







-
+







	} else {
		cx = args[0];
		cy = args[1];
		x2 = args[2];
		y2 = args[3];
	}

	// Convert to cubic bezier
	/* 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);

2120
2121
2122
2123
2124
2125
2126
2127

2128
2129
2130
2131
2132
2133
2134
2150
2151
2152
2153
2154
2155
2156

2157
2158
2159
2160
2161
2162
2163
2164







-
+







		x2 = args[0];
		y2 = args[1];
	}

	cx = 2*x1 - *cpx2;
	cy = 2*y1 - *cpy2;

	// Convert to cubix bezier
	/* 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);

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







-
+










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

-
+











-
+









-
-
-
+
+
+








-
+











-
+



-
+




-
-
+
+

-
-
+
+






-
+




-
-
+
+










-
-
+
+



















+







	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/)
	/* 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
	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
	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
		/* 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'
	/* 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'
	/* 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'
	/* 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.
	/* 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
	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 (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.
	/* 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.
	/* 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
		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) {
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
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







+






-
+







-
-
+
+



+







		}
	}

	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 (nsvg__isnum(item[0])) {
			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.
							/* 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':
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
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







-

-
+


-
+



+
+
+
+
-
+

-
+

-
+





-
+





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













-
+







							}
							break;
					}
					nargs = 0;
				}
			} else {
				cmd = item[0];
				rargs = nsvg__getArgsPerElement(cmd);
				if (cmd == 'M' || cmd == 'm') {
					// Commit path.
					/* Commit path. */
					if (p->npts > 0)
						nsvg__addPath(p, closedFlag);
					// Start new subpath.
					/* 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';
				}
				} else if (cmd == 'Z' || cmd == 'z') {
				if (cmd == 'Z' || cmd == 'z') {
					closedFlag = 1;
					// Commit path.
					/* Commit path. */
					if (p->npts > 0) {
						// Move current point to first point
						/* 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.
					/* 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.
				}
			}
		}
		/* 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 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));
2435
2436
2437
2438
2439
2440
2441
2442

2443
2444
2445
2446
2447
2448
2449
2477
2478
2479
2480
2481
2482
2483

2484
2485
2486
2487
2488
2489
2490
2491







-
+








		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
			/* 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);
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
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







-
+


-
+






-
+






-
+







				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
					/* No uniform scaling */
					p->alignType = NSVG_ALIGN_NONE;
				} else {
					// Parse X align
					/* 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
					/* 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
					/* Parse meet/slice */
					p->alignType = NSVG_ALIGN_MEET;
					if (strstr(attr[i + 1], "slice") != 0)
						p->alignType = NSVG_ALIGN_SLICE;
				}
			}
		}
	}
2704
2705
2706
2707
2708
2709
2710
2711

2712
2713
2714
2715
2716
2717
2718
2719

2720
2721
2722
2723
2724
2725
2726
2746
2747
2748
2749
2750
2751
2752

2753
2754
2755
2756
2757
2758
2759
2760

2761
2762
2763
2764
2765
2766
2767
2768







-
+







-
+







	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.
	/* 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
	/* Insert */
	idx = grad->nstops-1;
	for (i = 0; i < grad->nstops-1; i++) {
		if (curAttr->stopOffset < grad->stops[i].offset) {
			idx = i;
			break;
		}
	}
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
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







-
+














-
+







}

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
		/* 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.
		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);
2904
2905
2906
2907
2908
2909
2910
2911

2912
2913
2914
2915
2916
2917
2918
2946
2947
2948
2949
2950
2951
2952

2953
2954
2955
2956
2957
2958
2959
2960







-
+








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
	/* 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);
2926
2927
2928
2929
2930
2931
2932
2933

2934
2935
2936
2937
2938
2939
2940
2968
2969
2970
2971
2972
2973
2974

2975
2976
2977
2978
2979
2980
2981
2982







-
+







{
	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.
	/* 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];
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
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







-
+


-
+

-
+




-
+





-
+







	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
	/* Unit scaling */
	us = 1.0f / nsvg__convertToPixels(p, nsvg__coord(1.0f, nsvg__parseUnits(units)), 0.0f, 1.0f);

	// Fix aspect ratio
	/* Fix aspect ratio */
	if (p->alignType == NSVG_ALIGN_MEET) {
		// fit whole image into viewbox
		/* 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
		/* 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
	/* 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;
3023
3024
3025
3026
3027
3028
3029
3030

3031
3032
3033
3034
3035
3036
3037
3065
3066
3067
3068
3069
3070
3071

3072
3073
3074
3075
3076
3077
3078
3079







-
+







	if (p == NULL) {
		return NULL;
	}
	p->dpi = dpi;

	nsvg__parseXML(input, nsvg__startElement, nsvg__endElement, nsvg__content, p);

	// Scale to viewBox
	/* Scale to viewBox */
	nsvg__scaleToViewbox(p, units);

	ret = p->image;
	p->image = NULL;

	nsvg__deleteParser(p);

3050
3051
3052
3053
3054
3055
3056
3057

3058
3059
3060
3061
3062
3063
3064
3092
3093
3094
3095
3096
3097
3098

3099
3100
3101
3102
3103
3104
3105
3106







-
+







	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.
	data[size] = '\0';	/* Must be null terminated. */
	fclose(fp);
	image = nsvgParse(data, units, dpi);
	NANOSVG_free(data);

	return image;

error:

Changes to generic/nanosvgrast.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
55
56
57
58
59
60
61

62
63
64









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

79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
94







-
+


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



+

-
+







-
+







	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.
/* 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
/* 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.
/* Deletes rasterizer context. */
NANOSVG_SCOPE void nsvgDeleteRasterizer(NSVGrasterizer*);


#ifdef __cplusplus
}
#endif

#endif // NANOSVGRAST_H
#endif /* NANOSVGRAST_H */

#ifdef NANOSVGRAST_IMPLEMENTATION

#include <math.h>

#define NSVG__SUBSAMPLES	5
#define NSVG__FIXSHIFT		10
198
199
200
201
202
203
204
205

206
207
208
209
210

211
212
213
214
215

216
217
218
219
220
221
222
199
200
201
202
203
204
205

206
207
208
209
210

211
212
213
214
215

216
217
218
219
220
221
222
223







-
+




-
+




-
+







	NANOSVG_free(r);
}

static NSVGmemPage* nsvg__nextPage(NSVGrasterizer* r, NSVGmemPage* cur)
{
	NSVGmemPage *newp;

	// If using existing chain, return the next page in chain
	/* If using existing chain, return the next page in chain */
	if (cur != NULL && cur->next != NULL) {
		return cur->next;
	}

	// Alloc new page
	/* Alloc new page */
	newp = (NSVGmemPage*)NANOSVG_malloc(sizeof(NSVGmemPage));
	if (newp == NULL) return NULL;
	memset(newp, 0, sizeof(NSVGmemPage));

	// Add to linked list
	/* Add to linked list */
	if (cur != NULL)
		cur->next = newp;
	else
		r->pages = newp;

	return newp;
}
298
299
300
301
302
303
304
305

306
307
308
309
310
311
312
299
300
301
302
303
304
305

306
307
308
309
310
311
312
313







-
+







	r->npoints2 = r->npoints;
}

static void nsvg__addEdge(NSVGrasterizer* r, float x0, float y0, float x1, float y1)
{
	NSVGedge* e;

	// Skip horizontal edges
	/* 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;
384
385
386
387
388
389
390
391

392
393
394
395
396
397

398
399

400
401
402
403
404
405
406
385
386
387
388
389
390
391

392
393
394
395
396
397

398
399

400
401
402
403
404
405
406
407







-
+





-
+

-
+







static void 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
		/* 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
		/* Close path */
		nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0);
		// Build edges
		/* 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
{
615
616
617
618
619
620
621
622

623
624
625
626
627

628
629

630
631
632
633
634
635

636
637
638
639
640
641
642
643
644
645
646
647

648
649
650
651
652
653
654
616
617
618
619
620
621
622

623
624
625
626
627

628
629

630
631
632
633
634
635

636
637
638
639
640
641
642
643
644
645
646
647

648
649
650
651
652
653
654
655







-
+




-
+

-
+





-
+











-
+







	int 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.
	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
	/* Build stroke edges */
	if (closed) {
		// Looping
		/* Looping */
		p0 = &points[npoints-1];
		p1 = &points[0];
		s = 0;
		e = npoints;
	} else {
		// Add cap
		/* 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
		/* 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);
667
668
669
670
671
672
673
674

675
676
677
678

679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699

700
701
702
703

704
705
706
707

708
709
710
711
712
713
714
715
716

717
718
719
720
721
722
723
724
725
726
727
728
729

730
731
732

733
734
735
736
737

738
739
740
741
742
743
744
668
669
670
671
672
673
674

675
676
677
678

679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699

700
701
702
703

704
705
706
707

708
709
710
711
712
713
714
715
716

717
718
719
720
721
722
723
724
725
726
727
728
729

730
731
732

733
734
735
736
737

738
739
740
741
742
743
744
745







-
+



-
+




















-
+



-
+



-
+








-
+












-
+


-
+




-
+







		} else {
			nsvg__straightJoin(r, &left, &right, p1, lineWidth);
		}
		p0 = p1++;
	}

	if (closed) {
		// Loop it
		/* 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
		/* 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
		/* 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
		/* Advance */
		p0 = p1++;
	}

	// calculate joins
	/* 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
		/* 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.
		/* Clear flags, but keep the corner. */
		p1->flags = (p1->flags & NSVG_PT_CORNER) ? NSVG_PT_CORNER : 0;

		// Keep track of left turns.
		/* 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.
		/* 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++;
752
753
754
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
753
754
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







-
+











-
+
















-
+






-
+





-
+
















-
+





-
+




-
+



-
+













-
+







	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
		/* 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.
		/* 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.
			/* Duplicate points -> points2. */
			nsvg__duplicatePoints(r);

			r->npoints = 0;
 			cur = r->points2[0];
			nsvg__appendPathPoint(r, cur);

			// Figure out dash offset.
			/* 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
			/* 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
					/* 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
					/* 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
					/* Advance dash pattern */
					dashState = !dashState;
					idash = (idash+1) % shape->strokeDashCount;
					dashLen = shape->strokeDashArray[idash] * scale;
					// Restart
					/* 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
			/* 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);
		}
	}
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
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







-
+



-
+





-
-
+
+





-
+








static NSVGactiveEdge* nsvg__addActive(NSVGrasterizer* r, NSVGedge* e, float startPoint)
{
	 NSVGactiveEdge* z;
	float dxdy;

	if (r->freelist != NULL) {
		// Restore from freelist.
		/* Restore from freelist. */
		z = r->freelist;
		r->freelist = z->next;
	} else {
		// Alloc new edge.
		/* 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
/*	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->x -= off_x * FIX; */
	z->ey = e->y1;
	z->next = 0;
	z->dir = e->dir;

	return z;
}

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







-
+


-
+


-
+

-
+


-
+

-
+





-
-
-
+
+
+
+


-
+



-
+


-
+



-
+






-
+


-
+







{
	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
			/* 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
			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
				i = -1; /* clip */

			if (j < len) // add antialiasing for x1
			if (j < len) /* add antialiasing for x1 */
				scanline[j] = (unsigned char)(scanline[j] + (((x1 & NSVG__FIXMASK) * maxWeight) >> NSVG__FIXSHIFT));
			else
				j = len; // clip
				j = len; /* clip */

			for (++i; i < j; ++i) // fill pixels between x0 and x1
			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
/* 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
	/* non-zero winding fill */
	int x0 = 0, w = 0;

	if (fillRule == NSVG_FILLRULE_NONZERO) {
		// Non-zero
		/* Non-zero */
		while (e != NULL) {
			if (w == 0) {
				// if we're currently at zero, we need to record the edge start point
				/* 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 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
		/* Even-odd */
		while (e != NULL) {
			if (w == 0) {
				// if we're currently at zero, we need to record the edge start point
				/* 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;
		}
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
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







-
+




-
+














-
-
+
+







		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
			/* Premultiply */
			r = nsvg__div255(cr * a);
			g = nsvg__div255(cg * a);
			b = nsvg__div255(cb * a);

			// Blend over
			/* 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.
		/* 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;
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
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







-
+




-
+















-
-
-
+
+
+







			cg = (c >> 8) & 0xff;
			cb = (c >> 16) & 0xff;
			ca = (c >> 24) & 0xff;

			a = nsvg__div255((int)cover[0] * ca);
			ia = 255 - a;

			// Premultiply
			/* Premultiply */
			r = nsvg__div255(cr * a);
			g = nsvg__div255(cg * a);
			b = nsvg__div255(cb * a);

			// Blend over
			/* 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)
		/* 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;
1099
1100
1101
1102
1103
1104
1105
1106

1107
1108
1109
1110
1111

1112
1113
1114
1115
1116
1117
1118
1101
1102
1103
1104
1105
1106
1107

1108
1109
1110
1111
1112

1113
1114
1115
1116
1117
1118
1119
1120







-
+




-
+







			cg = (c >> 8) & 0xff;
			cb = (c >> 16) & 0xff;
			ca = (c >> 24) & 0xff;

			a = nsvg__div255((int)cover[0] * ca);
			ia = 255 - a;

			// Premultiply
			/* Premultiply */
			r = nsvg__div255(cr * a);
			g = nsvg__div255(cg * a);
			b = nsvg__div255(cb * a);

			// Blend over
			/* 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;
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
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







-
+







-
+



-
-
+
+



-
-
+
+


-
-
+
+



-
+

















-
+




-
+



-
+



-
+



-
+







-
+



-
+













-
+













-
+







}

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 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
			/* 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
			/* 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);
					*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
					z->x += z->dx; /* advance to position for current scanline */
					step = &((*step)->next); /* advance through list */
				}
			}

			// resort the list if needed
			/* 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
			/* 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
					/* find insertion point */
					if (active == NULL) {
						active = z;
					} else if (z->x < active->x) {
						// insert at front
						/* insert at front */
						z->next = active;
						active = z;
					} else {
						// find thing to insert AFTER
						/* 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
						/* 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
			/* now process all active edges in non-zero fashion */
			if (active != NULL)
				nsvg__fillActiveEdges(r->scanline, r->width, active, maxWeight, &xmin, &xmax, fillRule);
		}
		// Blit
		/* 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
	/* 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
	/* 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];
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
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







-
+








-
+


-
+











-
+

-
+








-
+


-
+







		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
			/* 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
			/* 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
			/* 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");
/*			dumpEdges(r, "edge.svg"); */

			// Scale and translate edges
			/* 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
			/* 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
			/* 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);

Changes to generic/tk.decls.

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







-
-
+
+







# tk.decls --
#
#	This file contains the declarations for all supported public
#	functions that are exported by the Tk library via the stubs table.
#	This file is used to generate the tkDecls.h, tkPlatDecls.h,
#	tkStub.c, and tkPlatStub.c files.
#
# Copyright (c) 1998-2000 Ajuba Solutions.
# Copyright (c) 2007 Daniel A. Steffen <[email protected]>
# Copyright © 1998-2000 Ajuba Solutions.
# Copyright © 2007 Daniel A. Steffen <[email protected]>
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

library tk

# Define the tk interface with 3 sub interfaces:
399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413







-
+







    GC Tk_GetGC(Tk_Window tkwin, unsigned long valueMask, XGCValues *valuePtr)
}
declare 97 {
    Tk_Image Tk_GetImage(Tcl_Interp *interp, Tk_Window tkwin, const char *name,
	    Tk_ImageChangedProc *changeProc, ClientData clientData)
}
declare 98 {
    ClientData Tk_GetImageMasterData(Tcl_Interp *interp,
    ClientData Tk_GetImageModelData(Tcl_Interp *interp,
	    const char *name, const Tk_ImageType **typePtrPtr)
}
declare 99 {
    Tk_ItemType *Tk_GetItemTypes(void)
}
declare 100 {
    int Tk_GetJoinStyle(Tcl_Interp *interp, const char *str, int *joinPtr)
468
469
470
471
472
473
474
475

476
477
478
479
480
481
482
483
484
485
486
487
488
489
490


491
492
493
494
495
496
497
468
469
470
471
472
473
474

475
476
477
478
479
480
481
482
483
484
485
486
487
488


489
490
491
492
493
494
495
496
497







-
+













-
-
+
+







declare 115 {
    void Tk_HandleEvent(XEvent *eventPtr)
}
declare 116 {
    Tk_Window Tk_IdToWindow(Display *display, Window window)
}
declare 117 {
    void Tk_ImageChanged(Tk_ImageMaster master, int x, int y,
    void Tk_ImageChanged(Tk_ImageModel model, int x, int y,
	    int width, int height, int imageWidth, int imageHeight)
}
declare 118 {
    int Tk_Init(Tcl_Interp *interp)
}
declare 119 {
    Atom Tk_InternAtom(Tk_Window tkwin, const char *name)
}
declare 120 {
    int Tk_IntersectTextLayout(Tk_TextLayout layout, int x, int y,
	    int width, int height)
}
declare 121 {
    void Tk_MaintainGeometry(Tk_Window slave,
	    Tk_Window master, int x, int y, int width, int height)
    void Tk_MaintainGeometry(Tk_Window window,
	    Tk_Window container, int x, int y, int width, int height)
}
declare 122 {
    Tk_Window Tk_MainWindow(Tcl_Interp *interp)
}
declare 123 {
    void Tk_MakeWindowExist(Tk_Window tkwin)
}
535
536
537
538
539
540
541
542

543
544
545
546
547
548
549
535
536
537
538
539
540
541

542
543
544
545
546
547
548
549







-
+







declare 135 {
    const char *Tk_NameOfCursor(Display *display, Tk_Cursor cursor)
}
declare 136 {
    const char *Tk_NameOfFont(Tk_Font font)
}
declare 137 {
    const char *Tk_NameOfImage(Tk_ImageMaster imageMaster)
    const char *Tk_NameOfImage(Tk_ImageModel model)
}
declare 138 {
    const char *Tk_NameOfJoinStyle(int join)
}
declare 139 {
    const char *Tk_NameOfJustify(Tk_Justify justify)
}
688
689
690
691
692
693
694
695

696
697
698
699
700
701
702
688
689
690
691
692
693
694

695
696
697
698
699
700
701
702







-
+







	    Tk_TextLayout layout, int x, int y,
	    int underline)
}
declare 180 {
    void Tk_Ungrab(Tk_Window tkwin)
}
declare 181 {
    void Tk_UnmaintainGeometry(Tk_Window slave, Tk_Window master)
    void Tk_UnmaintainGeometry(Tk_Window window, Tk_Window container)
}
declare 182 {
    void Tk_UnmapWindow(Tk_Window tkwin)
}
declare 183 {
    void Tk_UnsetGrid(Tk_Window tkwin)
}
1064
1065
1066
1067
1068
1069
1070
1071


1072






















1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
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







-
+
+

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



-







# build against legacy sources.
declare 272 {
    void Tk_CreateOldImageType(const Tk_ImageType *typePtr)
}
declare 273 {
    void Tk_CreateOldPhotoImageFormat(const Tk_PhotoImageFormat *formatPtr)
}
# New in Tk8.7

# TIP#580
declare 274 {
    int Tk_AlwaysShowSelection(Tk_Window tkwin)
}
declare 275 {
    unsigned Tk_GetButtonMask(unsigned button)
}
declare 276 {
    int Tk_GetDoublePixelsFromObj(Tcl_Interp *interp, Tk_Window tkwin,
	    Tcl_Obj *objPtr, double *doublePtr)
}
declare 277 {
    Tcl_Obj *Tk_NewWindowObj(Tk_Window tkwin)
}
declare 278 {
    void Tk_SendVirtualEvent(Tk_Window tkwin, const char *eventName,
	    Tcl_Obj *detail)
}
declare 279 {
    Tcl_Obj *Tk_FontGetDescription(Tk_Font tkfont)
}

# TIP#529
declare 280 {
    void Tk_CreatePhotoImageFormatVersion3(
	    const Tk_PhotoImageFormatVersion3 *formatPtr)
}


# Define the platform specific public Tk interface.  These functions are
# only available on the designated platform.

interface tkPlat

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







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




-
+





+
-
-
+
+
-
+










-
+
-
-
-
-
-


-
+

+

-
+

-
-
-
-
-
-

-
+







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 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 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 {
    void Tk_MacOSXSetEmbedHandler_(
    Tk_Window Tk_MacOSXGetTkWindow(void *w)
	    Tk_MacOSXEmbedRegisterWinProc *registerWinProcPtr,
	    Tk_MacOSXEmbedGetGrafPortProc *getPortProcPtr,
	    Tk_MacOSXEmbedMakeContainerExistProc *containerExistProcPtr,
	    Tk_MacOSXEmbedGetClipProc *getClipProc,
	    Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc)
}
declare 12 aqua {
    void Tk_MacOSXTurnOffMenus_(void)
    void *Tk_MacOSXGetCGContextForDrawable(Drawable drawable)
}
# Replaces TkMacOSXDrawable
declare 13 aqua {
    void Tk_MacOSXTkOwnsCursor_(int tkOwnsIt)
    void *Tk_MacOSXGetNSWindowForDrawable(Drawable drawable)
}
declare 14 aqua {
    void TkMacOSXInitMenus_(Tcl_Interp *interp)
}
declare 15 aqua {
    void TkMacOSXInitAppleEvents_(Tcl_Interp *interp)
}
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.

90
91
92
93
94
95
96
97
98
99

100
101
102
103
104
105
106
107
90
91
92
93
94
95
96



97

98
99
100
101
102
103
104







-
-
-
+
-







#   pragma GCC diagnostic ignored "-Wc++-compat"
#endif
#   include <X11/Xlib.h>
#   ifdef MAC_OSX_TK
#	include <X11/X.h>
#   endif
#endif
#if defined(STDC_HEADERS) || defined(__STDC__) || defined(__C99__FUNC__) \
     || defined(__cplusplus) || defined(_MSC_VER) || defined(__ICC)
#   include <stddef.h>
#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
118
119
120
121
122
123
124

125
126
127
128
129
130
131

132
133
134
135
136
137
138
115
116
117
118
119
120
121
122
123
124
125
126
127
128

129
130
131
132
133
134
135
136







+






-
+







#define TK_USE_INPUT_METHODS
#endif

/*
 * Dummy types that are used by clients:
 */

#define Tk_ImageMaster Tk_ImageModel
typedef struct Tk_BindingTable_ *Tk_BindingTable;
typedef struct Tk_Canvas_ *Tk_Canvas;
typedef struct Tk_Cursor_ *Tk_Cursor;
typedef struct Tk_ErrorHandler_ *Tk_ErrorHandler;
typedef struct Tk_Font_ *Tk_Font;
typedef struct Tk_Image__ *Tk_Image;
typedef struct Tk_ImageMaster_ *Tk_ImageMaster;
typedef struct Tk_ImageModel_ *Tk_ImageModel;
typedef struct Tk_OptionTable_ *Tk_OptionTable;
typedef struct Tk_PostscriptInfo_ *Tk_PostscriptInfo;
typedef struct Tk_TextLayout_ *Tk_TextLayout;
typedef struct Tk_Window_ *Tk_Window;
typedef struct Tk_3DBorder_ *Tk_3DBorder;
typedef struct Tk_Style_ *Tk_Style;
typedef struct Tk_StyleEngine_ *Tk_StyleEngine;
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
644
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







+

-
+






-
+

-
-
+
+


-
+








/*
 * Each geometry manager (the packer, the placer, etc.) is represented by a
 * structure of the following form, which indicates procedures to invoke in
 * the geometry manager to carry out certain functions.
 */

#define Tk_GeomLostSlaveProc Tk_GeomLostContentProc
typedef void (Tk_GeomRequestProc) (ClientData clientData, Tk_Window tkwin);
typedef void (Tk_GeomLostSlaveProc) (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 slave's
				/* Procedure to invoke when a content's
				 * requested geometry changes. */
    Tk_GeomLostSlaveProc *lostSlaveProc;
				/* Procedure to invoke when a slave is taken
    Tk_GeomLostContentProc *lostContentProc;
				/* Procedure to invoke when content is taken
				 * away from one geometry manager by another.
				 * NULL means geometry manager doesn't care
				 * when slaves are lost. */
				 * when content lost. */
} Tk_GeomMgr;

/*
 * Result values returned by Tk_GetScrollInfo:
 */

#define TK_SCROLL_MOVETO	1
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
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







-
-
+
+


-
-
+
+

-
-
+
+


-
-
+
+







 *
 *----------------------------------------------------------------------
 */

typedef struct Tk_ImageType Tk_ImageType;
#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 && defined(USE_OLD_IMAGE)
typedef int (Tk_ImageCreateProc) (Tcl_Interp *interp, char *name, int argc,
	char **argv, Tk_ImageType *typePtr, Tk_ImageMaster master,
	ClientData *masterDataPtr);
	char **argv, Tk_ImageType *typePtr, Tk_ImageModel model,
	ClientData *clientDataPtr);
#else
typedef int (Tk_ImageCreateProc) (Tcl_Interp *interp, const char *name, int objc,
	Tcl_Obj *const objv[], const Tk_ImageType *typePtr, Tk_ImageMaster master,
	ClientData *masterDataPtr);
	Tcl_Obj *const objv[], const Tk_ImageType *typePtr, Tk_ImageModel model,
	ClientData *clientDataPtr);
#endif /* USE_OLD_IMAGE */
typedef ClientData (Tk_ImageGetProc) (Tk_Window tkwin, ClientData masterData);
typedef void (Tk_ImageDisplayProc) (ClientData instanceData, Display *display,
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 instanceData, Display *display);
typedef void (Tk_ImageDeleteProc) (ClientData masterData);
typedef void (Tk_ImageFreeProc) (ClientData clientData, Display *display);
typedef void (Tk_ImageDeleteProc) (ClientData clientData);
typedef void (Tk_ImageChangedProc) (ClientData clientData, int x, int y,
	int width, int height, int imageWidth, int imageHeight);
typedef int (Tk_ImagePostscriptProc) (ClientData clientData,
	Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psinfo,
	int x, int y, int width, int height, int prepass);

/*

Changes to generic/tk3d.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






-
-
+
+







/*
 * tk3d.c --
 *
 *	This module provides procedures to draw borders in the
 *	three-dimensional Motif style.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tk3d.h"

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

Changes to generic/tkArgv.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






-
-
+
+







/*
 * tkArgv.c --
 *
 *	This file contains a function that handles table-based argv-argc
 *	parsing.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

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

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








-
-
+
+







/*
 * tkAtom.c --
 *
 *	This file manages a cache of X Atoms in order to avoid interactions
 *	with the X server. It's much like the Xmu routines, except it has a
 *	cleaner interface (caller doesn't have to provide permanent storage
 *	for atom names, for example).
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994 Sun Microsystems, Inc.
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

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 © 1989-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1998 Scriptics Corporation.
 * Copyright © 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"
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150

151
152
153
154
155
156
157
133
134
135
136
137
138
139







140
141
142

143
144
145
146
147
148
149
150







-
-
-
-
-
-
-



-
+







    unsigned countAny;	/* Count of multi-events, like multi-clicks, or repeated key pressing,
    			 * this count does not depend on detail (keySym or button). */
    unsigned countDetailed;
    			/* Count of multi-events, like multi-clicks, or repeated key pressing,
    			 * this count considers the detail (keySym or button). */
} Event;

/*
 * We need a structure providing a list of pattern sequences.
 */

typedef unsigned EventMask;
typedef unsigned long ModMask;

struct PatSeq; /* forward declaration */

/* We need this array for bookkeeping the last matching modifier mask per pattern. */
TK_ARRAY_DEFINE(PSModMaskArr, ModMask);
TK_ARRAY_DEFINE(PSModMaskArr, unsigned);

typedef struct PSEntry {
    TK_DLIST_LINKS(PSEntry);	/* Makes this struct a double linked list; must be first entry. */
    Window window;		/* Window of last match. */
    struct PatSeq* psPtr;	/* Pointer to pattern sequence. */
    PSModMaskArr *lastModMaskArr;
    				/* Last matching modifier mask per pattern (except last pattern).
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







-
+







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. */
    ModMask curModMask;		/* Containing the current modifier mask. */
    unsigned curModMask;		/* Containing the current modifier mask. */
    LookupTables lookupTables;	/* Containing hash tables for fast lookup. */
    Tcl_HashTable objectTable;	/* Used to map from an object to a list of patterns associated with
    				 * that object. Keys are ClientData, values are (PatSeq *). */
    Tcl_Interp *interp;		/* Interpreter in which commands are executed. */
} BindingTable;

/*
261
262
263
264
265
266
267
268

269
270
271
272
273
274
275
254
255
256
257
258
259
260

261
262
263
264
265
266
267
268







-
+







 * For technical reasons we do not use 'union Detail', although this would
 * be possible, instead 'info' and 'name' are both included.
 */

typedef struct {
    unsigned eventType;		/* Type of X event, e.g. ButtonPress. */
    unsigned count;		/* Multi-event count, e.g. double-clicks, triple-clicks, etc. */
    ModMask modMask;		/* Mask of modifiers that must be present (zero means no modifiers
    unsigned modMask;		/* Mask of modifiers that must be present (zero means no modifiers
    				 * are required). */
    Info info;			/* Additional information that must match event. Normally this is zero,
    				 * meaning no additional information must match. For KeyPress and
				 * KeyRelease events, it may be specified to select a particular
				 * keystroke (zero means any keystrokes). For button events, specifies
				 * a particular button (zero means any buttons are OK). */
    Tk_Uid name;		/* Specifies the Tk_Uid of the virtual event name. NULL if not a
412
413
414
415
416
417
418
419

420
421
422
423
424
425
426
405
406
407
408
409
410
411

412
413
414
415
416
417
418
419







-
+







 * information about those modifiers. The structure for storing this
 * information, and the hash table built at initialization time, are defined
 * below.
 */

typedef struct {
    const char *name;	/* Name of modifier. */
    ModMask mask;	/* Button/modifier mask value, such as Button1Mask. */
    unsigned mask;	/* Button/modifier mask value, such as Button1Mask. */
    unsigned flags;	/* Various flags; see below for definitions. */
} ModInfo;

/*
 * Flags for ModInfo structures:
 *
 * DOUBLE -		Non-zero means duplicate this event, e.g. for double-clicks.
435
436
437
438
439
440
441

442

443
444
445
446
447
448
449
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444







+

+







#define MULT_CLICKS	(DOUBLE|TRIPLE|QUADRUPLE)

static const ModInfo modArray[] = {
    {"Control",		ControlMask,	0},
    {"Shift",		ShiftMask,	0},
    {"Lock",		LockMask,	0},
    {"Meta",		META_MASK,	0},
#ifndef TK_NO_DEPRECATED
    {"M",		META_MASK,	0},
#endif
    {"Alt",		ALT_MASK,	0},
    {"Extended",	EXTENDED_MASK,	0},
    {"B1",		Button1Mask,	0},
    {"Button1",		Button1Mask,	0},
    {"B2",		Button2Mask,	0},
    {"Button2",		Button2Mask,	0},
    {"B3",		Button3Mask,	0},
458
459
460
461
462
463
464

465





466
467

468



469
470
471
472
473
474
475
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480







+

+
+
+
+
+


+

+
+
+







    {"Button7",		Button7Mask,	0},
    {"B8",		Button8Mask,	0},
    {"Button8",		Button8Mask,	0},
    {"B9",		Button9Mask,	0},
    {"Button9",		Button9Mask,	0},
    {"Mod1",		Mod1Mask,	0},
    {"M1",		Mod1Mask,	0},
#ifdef MAC_OSX_TK
    {"Command",		Mod1Mask,	0},
#elif defined (_WIN32)
    {"Command",		ControlMask,	0},
#else
    {"Command",		META_MASK,	0},
#endif
    {"Mod2",		Mod2Mask,	0},
    {"M2",		Mod2Mask,	0},
#ifdef MAC_OSX_TK
    {"Option",		Mod2Mask,	0},
#else
    {"Option",		ALT_MASK,	0},
#endif
    {"Mod3",		Mod3Mask,	0},
    {"M3",		Mod3Mask,	0},
    {"Mod4",		Mod4Mask,	0},
    {"M4",		Mod4Mask,	0},
    {"Mod5",		Mod5Mask,	0},
    {"M5",		Mod5Mask,	0},
    {"Double",		0,		DOUBLE},
497
498
499
500
501
502
503

504

505
506

507

508
509
510
511
512
513
514
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523







+

+


+

+







 * This is necessary because X doesn't report up events unless you also ask
 * for down events. Also, X doesn't report button state in motion events
 * unless you've asked about button events.
 */

static const EventInfo eventArray[] = {
    {"Key",		KeyPress,		KeyPressMask},
#ifndef TK_NO_DEPRECATED
    {"KeyPress",	KeyPress,		KeyPressMask},
#endif
    {"KeyRelease",	KeyRelease,		KeyPressMask|KeyReleaseMask},
    {"Button",		ButtonPress,		ButtonPressMask},
#ifndef TK_NO_DEPRECATED
    {"ButtonPress",	ButtonPress,		ButtonPressMask},
#endif
    {"ButtonRelease",	ButtonRelease,		ButtonPressMask|ButtonReleaseMask},
    {"Motion",		MotionNotify,		ButtonPressMask|PointerMotionMask},
    {"Enter",		EnterNotify,		EnterWindowMask},
    {"Leave",		LeaveNotify,		LeaveWindowMask},
    {"FocusIn",		FocusIn,		FocusChangeMask},
    {"FocusOut",	FocusOut,		FocusChangeMask},
    {"Expose",		Expose,			ExposureMask},
717
718
719
720
721
722
723
724

725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740

741
742
743
744
745
746
747
748
726
727
728
729
730
731
732

733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748

749

750
751
752
753
754
755
756







-
+















-
+
-







static int		DeleteVirtualEvent(Tcl_Interp *interp, VirtualEventTable *vetPtr,
			    char *virtString, const char *eventString);
static void		DeleteVirtualEventTable(VirtualEventTable *vetPtr);
static void		ExpandPercents(TkWindow *winPtr, const char *before, Event *eventPtr,
			    unsigned scriptCount, Tcl_DString *dsPtr);
static PatSeq *		FindSequence(Tcl_Interp *interp, LookupTables *lookupTables,
			    ClientData object, const char *eventString, int create,
			    int allowVirtual, EventMask *maskPtr);
			    int allowVirtual, unsigned *maskPtr);
static void		GetAllVirtualEvents(Tcl_Interp *interp, VirtualEventTable *vetPtr);
static const char *	GetField(const char *p, char *copy, unsigned size);
static Tcl_Obj *	GetPatternObj(const PatSeq *psPtr);
static int		GetVirtualEvent(Tcl_Interp *interp, VirtualEventTable *vetPtr,
			    Tcl_Obj *virtName);
static Tk_Uid		GetVirtualEventUid(Tcl_Interp *interp, char *virtString);
static int		HandleEventGenerate(Tcl_Interp *interp, Tk_Window main,
			    int objc, Tcl_Obj *const objv[]);
static void		InitVirtualEventTable(VirtualEventTable *vetPtr);
static PatSeq *		MatchPatterns(TkDisplay *dispPtr, Tk_BindingTable bindPtr, PSList *psList,
			    PSList *psSuccList, unsigned patIndex, const Event *eventPtr,
			    ClientData object, PatSeq **physPtrPtr);
static int		NameToWindow(Tcl_Interp *interp, Tk_Window main,
			    Tcl_Obj *objPtr, Tk_Window *tkwinPtr);
static unsigned		ParseEventDescription(Tcl_Interp *interp, const char **eventStringPtr,
			    TkPattern *patPtr, EventMask *eventMaskPtr);
			    TkPattern *patPtr, unsigned *eventMaskPtr);
static void		DoWarp(ClientData 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 PSEntry *	MakeListEntry(PSList *pool, PatSeq *psPtr, int needModMasks);
static void		RemovePatSeqFromLookup(LookupTables *lookupTables, PatSeq *psPtr);
static void		RemovePatSeqFromPromotionLists(Tk_BindingTable bindPtr, PatSeq *psPtr);
765
766
767
768
769
770
771
772
773


774
775
776
777
778
779
780
773
774
775
776
777
778
779


780
781
782
783
784
785
786
787
788







-
-
+
+







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(
    ModMask lhsMask,	/* this is a subset */
    ModMask rhsMask)	/* of this bit field? */
    unsigned lhsMask,	/* this is a subset */
    unsigned rhsMask)	/* of this bit field? */
{
    return (lhsMask & rhsMask) == lhsMask;
}

static const char*
SkipSpaces(
    const char* s)
796
797
798
799
800
801
802

803
804


805
806
807
808
809
810
811
804
805
806
807
808
809
810
811
812

813
814
815
816
817
818
819
820
821







+

-
+
+







    return s;
}

static unsigned
GetButtonNumber(
    const char *field)
{
    unsigned button;
    assert(field);
    return (field[0] >= '1' && field[0] <= '9' && field[1] == '\0') ? field[0] - '0' : 0;
    button = (field[0] >= '1' && field[0] <= '9' && field[1] == '\0') ? field[0] - '0' : 0;
    return (button > 3) ? (button + 4) : button;
}

static Time
CurrentTimeInMilliSecs(void)
{
    Tcl_Time now;
    Tcl_GetTime(&now);
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
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







-
+



-















-
+





-
+









-
+







    } else {
	PSList_Move(pool, psList);
    }
}

static PSEntry *
FreePatSeqEntry(
    PSList *pool,
    TCL_UNUSED(PSList *),
    PSEntry *entry)
{
    PSEntry *next = PSList_Next(entry);
    (void)pool;

    PSModMaskArr_Free(&entry->lastModMaskArr);
    ckfree(entry);
    return next;
}

static unsigned
ResolveModifiers(
    TkDisplay *dispPtr,
    unsigned modMask)
{
    assert(dispPtr);

    if (dispPtr->metaModMask) {
	if (modMask & META_MASK) {
	    modMask &= ~(ModMask)META_MASK;
	    modMask &= ~META_MASK;
	    modMask |= dispPtr->metaModMask;
	}
    }
    if (dispPtr->altModMask) {
	if (modMask & ALT_MASK) {
	    modMask &= ~(ModMask)ALT_MASK;
	    modMask &= ~ALT_MASK;
	    modMask |= dispPtr->altModMask;
	}
    }

    return modMask;
}

static int
ButtonNumberFromState(
    ModMask state)
    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; }
1644
1645
1646
1647
1648
1649
1650
1651

1652
1653
1654
1655
1656
1657
1658
1653
1654
1655
1656
1657
1658
1659

1660
1661
1662
1663
1664
1665
1666
1667







-
+







    const char *script,		/* Contains Tcl script to execute when binding triggers. */
    int append)			/* 0 means replace any existing binding for eventString;
    				 * 1 means append to that binding. If the existing binding is
				 * for a callback function and not a Tcl command string, the
				 * existing binding will always be replaced. */
{
    PatSeq *psPtr;
    EventMask eventMask;
    unsigned eventMask;
    char *oldStr;
    char *newStr;

    assert(bindPtr);
    assert(object);
    assert(eventString);
    assert(script);
2169
2170
2171
2172
2173
2174
2175
2176

2177
2178
2179
2180
2181
2182
2183
2178
2179
2180
2181
2182
2183
2184

2185
2186
2187
2188
2189
2190
2191
2192







-
+







    ClientData *objArr)		/* Array of one or more objects to check for a matching binding. */
{
    Tcl_Interp *interp;
    ScreenInfo *screenPtr;
    TkDisplay *dispPtr;
    TkDisplay *oldDispPtr;
    Event *curEvent;
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *winPtr = (TkWindow *)tkwin;
    BindInfo *bindInfoPtr;
    Tcl_InterpState interpState;
    LookupTables *physTables;
    PatSeq *psPtr[2];
    PatSeq *matchPtrBuf[32];
    PatSeq **matchPtrArr = matchPtrBuf;
    PSList *psl[2];
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2468
2469
2470
2471
2472
2473
2474

2475
2476
2477
2478
2479
2480
2481







-








	    matchPtrArr[k] = bestPtr;

	    if (eventPtr->type != VirtualEvent) {
		LookupTables *virtTables = &bindInfoPtr->virtualEventTable.lookupTables;
		PatSeq *matchPtr = matchPtrArr[k];
		PatSeq *mPtr;
		PSList *psl[2];

		/*
		 * Note that virtual events cannot promote.
		 */

		psl[0] = GetLookupForEvent(virtTables, curEvent, NULL, 1);
		psl[1] = GetLookupForEvent(virtTables, curEvent, NULL, 0);
2737
2738
2739
2740
2741
2742
2743
2744
2745


2746
2747
2748
2749
2750
2751
2752
2745
2746
2747
2748
2749
2750
2751


2752
2753
2754
2755
2756
2757
2758
2759
2760







-
-
+
+







}

/* helper function */
static int
CompareModMasks(
    const PSModMaskArr *fstModMaskArr,
    const PSModMaskArr *sndModMaskArr,
    ModMask fstModMask,
    ModMask sndModMask)
    unsigned fstModMask,
    unsigned sndModMask)
{
    int fstCount = 0;
    int sndCount = 0;
    int i;

    if (PSModMaskArr_IsEmpty(fstModMaskArr)) {
	if (!PSModMaskArr_IsEmpty(sndModMaskArr)) {
2762
2763
2764
2765
2766
2767
2768
2769
2770


2771
2772
2773


2774
2775
2776
2777
2778
2779
2780
2770
2771
2772
2773
2774
2775
2776


2777
2778
2779


2780
2781
2782
2783
2784
2785
2786
2787
2788







-
-
+
+

-
-
+
+







		++fstCount;
	    }
	}
    } else {
	assert(PSModMaskArr_Size(fstModMaskArr) == PSModMaskArr_Size(sndModMaskArr));

	for (i = PSModMaskArr_Size(fstModMaskArr) - 1; i >= 0; --i) {
	    ModMask fstModMask = *PSModMaskArr_Get(fstModMaskArr, i);
	    ModMask sndModMask = *PSModMaskArr_Get(sndModMaskArr, i);
	    unsigned fstiModMask = *PSModMaskArr_Get(fstModMaskArr, i);
	    unsigned sndiModMask = *PSModMaskArr_Get(sndModMaskArr, i);

	    if (IsSubsetOf(fstModMask, sndModMask)) { ++sndCount; }
	    if (IsSubsetOf(sndModMask, fstModMask)) { ++fstCount; }
	    if (IsSubsetOf(fstiModMask, sndiModMask)) { ++sndCount; }
	    if (IsSubsetOf(sndiModMask, fstiModMask)) { ++fstCount; }
	}
    }

    /* Finally compare modifier masks of last pattern. */

    if (IsSubsetOf(fstModMask, sndModMask)) { ++sndCount; }
    if (IsSubsetOf(sndModMask, fstModMask)) { ++fstCount; }
2796
2797
2798
2799
2800
2801
2802
2803

2804
2805
2806
2807
2808
2809
2810
2804
2805
2806
2807
2808
2809
2810

2811
2812
2813
2814
2815
2816
2817
2818







-
+







    				 * Output: the associated physical event for the best matching virtual
				 * event; NULL when we match physical events. */
{
    Window window;
    PSEntry *psEntry;
    PatSeq *bestPtr;
    PatSeq *bestPhysPtr;
    ModMask bestModMask;
    unsigned bestModMask;
    const PSModMaskArr *bestModMaskArr = NULL;
    int i, isModKeyOnly = 0;

    assert(dispPtr);
    assert(bindPtr);
    assert(curEvent);

2863
2864
2865
2866
2867
2868
2869
2870
2871


2872
2873
2874
2875
2876
2877
2878
2871
2872
2873
2874
2875
2876
2877


2878
2879
2880
2881
2882
2883
2884
2885
2886







-
-
+
+







			&& (!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.
		     */
		    ModMask modMask = ResolveModifiers(dispPtr, patPtr->modMask);
		    ModMask curModMask = ResolveModifiers(dispPtr, bindPtr->curModMask);
		    unsigned modMask = ResolveModifiers(dispPtr, patPtr->modMask);
		    unsigned curModMask = ResolveModifiers(dispPtr, bindPtr->curModMask);

		    psEntry->expired = 1; /* remove it from promotion list */
                    psEntry->keepIt = 0; /* don't keep matching patterns */

		    if (IsSubsetOf(modMask, curModMask)) {
			unsigned count = patPtr->info ? curEvent->countDetailed : curEvent->countAny;

2998
2999
3000
3001
3002
3003
3004
3005
3006


3007
3008
3009
3010
3011
3012
3013
3006
3007
3008
3009
3010
3011
3012


3013
3014
3015
3016
3017
3018
3019
3020
3021







-
-
+
+







	snprintf(numStorage, sizeof(numStorage), "%" TCL_LL_MODIFIER "u", unumber);	\
	string = numStorage;						\
    }

    while (1) {
	char numStorage[TCL_INTEGER_SPACE];
	const char *string;
	Tcl_WideInt number;     /* signed */
	Tcl_WideUInt unumber;   /* unsigned */
	long long number;     /* signed */
	unsigned long long unumber;   /* unsigned */

	/*
	 * Find everything up to the next % character and append it to the
	 * result string.
	 */

	for (string = before; *string && *string != '%'; ++string)
3516
3517
3518
3519
3520
3521
3522
3523

3524
3525
3526
3527
3528
3529
3530
3524
3525
3526
3527
3528
3529
3530

3531
3532
3533
3534
3535
3536
3537
3538







-
+







 *
 * CreateVirtualEvent --
 *
 *	Add a new definition for a virtual event. If the virtual event is
 *	already defined, the new definition augments those that already exist.
 *
 * Results:
 *	The return value is TCL_ERROR if an error occured while creating the
 *	The return value is TCL_ERROR if an error occurred while creating the
 *	virtual binding. In this case, an error message will be left in the
 *	interp's result. If all went well then the return value is TCL_OK.
 *
 * Side effects:
 *	The virtual event may cause future calls to Tk_BindEvent to behave
 *	differently than they did previously.
 *
3860
3861
3862
3863
3864
3865
3866
3867

3868
3869
3870
3871
3872
3873
3874
3868
3869
3870
3871
3872
3873
3874

3875
3876
3877
3878
3879
3880
3881
3882







-
+







    const char *name;
    const char *windowName;
    Tcl_QueuePosition pos;
    TkPattern pat;
    Tk_Window tkwin;
    Tk_Window tkwin2;
    TkWindow *mainPtr;
    EventMask eventMask;
    unsigned eventMask;
    Tcl_Obj *userDataObj;
    int synch;
    int warp;
    unsigned count;
    unsigned flags;
    int number;
    unsigned i;
4044
4045
4046
4047
4048
4049
4050



4051
4052
4053
4054
4055
4056
4057
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068







+
+
+







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







-
-
-
-
-
-
-
-
-
-
-









-
-
-
-
-












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







	     * refcount before firing it into the low-level event subsystem; the
	     * refcount will be decremented once the event has been processed.
	     */
	    event.virt.user_data = userDataObj;
	    Tcl_IncrRefCount(userDataObj);
	}

	/*
	 * Now we have constructed the event, inject it into the event handling
	 * code.
	 */

	if (synch) {
	    Tk_HandleEvent(&event.general);
	} else {
	    Tk_QueueWindowEvent(&event.general, pos);
	}

	/*
	 * We only allow warping if the window is mapped.
	 */

	if (warp && Tk_IsMapped(tkwin)) {
	    TkDisplay *dispPtr = TkGetDisplay(event.general.xmotion.display);

	    Tk_Window warpWindow = Tk_IdToWindow(dispPtr->display, event.general.xmotion.window);

	    if (!(dispPtr->flags & TK_DISPLAY_IN_WARP)) {
		Tcl_DoWhenIdle(DoWarp, dispPtr);
		dispPtr->flags |= TK_DISPLAY_IN_WARP;
	    }

	    if (warpWindow != dispPtr->warpWindow) {
		if (warpWindow) {
		    Tcl_Preserve(warpWindow);
		}
		if (dispPtr->warpWindow) {
		    Tcl_Release(dispPtr->warpWindow);
		}
		dispPtr->warpWindow = warpWindow;
	    }
	    dispPtr->warpMainwin = mainWin;
	    dispPtr->warpX = event.general.xmotion.x;
	    dispPtr->warpY = event.general.xmotion.y;

            /*
             * Warping with respect to a window will be done when Tk_handleEvent
             * below will run the event handlers and in particular TkPointerEvent.
             * This allows to make grabs and warping work together robustly, that
             * is without depending on a precise sequence of events.
             * Warping with respect to the whole screen (i.e. dispPtr->warpWindow
             * is NULL) is run directly here.
             */

            if (!dispPtr->warpWindow) {
                TkpWarpPointer(dispPtr);
                XForceScreenSaver(dispPtr->display, ScreenSaverReset);
            }
	}

	/*
	 * Now we have constructed the event, inject it into the event handling
	 * code.
	 */

	if (synch) {
	    Tk_HandleEvent(&event.general);
	} else {
	    Tk_QueueWindowEvent(&event.general, pos);
	}
    }

    Tcl_ResetResult(interp);
    return TCL_OK;
}
/*
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
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







-
+

-
+





-
+




-
-
-
+
+
+

-
+

+
+
+
+
-
+
+

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

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

-







    *tkwinPtr = tkwin;
    return 1;
}

/*
 *-------------------------------------------------------------------------
 *
 * DoWarp --
 * TkDoWarpWrtWin --
 *
 *	Perform Warping of X pointer. Executed as an idle handler only.
 *	Perform warping of mouse pointer with respect to a window.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	X Pointer will move to a new location.
 *	Mouse pointer moves to a new location.
 *
 *-------------------------------------------------------------------------
 */

static void
DoWarp(
    ClientData clientData)
void
TkDoWarpWrtWin(
    TkDisplay *dispPtr)
{
    TkDisplay *dispPtr = (TkDisplay *)clientData;
    assert(dispPtr);

    /*
     * A NULL warpWindow means warping with respect to the whole screen.
     * We want to warp here only if we're warping with respect to a window.
     */
    assert(clientData);

    if (dispPtr->warpWindow) {

    /*
     * DoWarp was scheduled only if the window was mapped. It needs to be
     * still mapped at the time the present idle callback is executed. Also
     * one needs to guard against window destruction in the meantime.
        /*
         * Warping with respect to a window can only be done if the window is
         * mapped. This was checked in HandleEvent. The window needs to be
         * still mapped at the time the present code is executed. Also
         * one needs to guard against window destruction in the meantime,
     * Finally, the case warpWindow == NULL is special in that it means
     * the whole screen.
     */
         * which could have happened as a side effect of an event handler.
         */

    if (!dispPtr->warpWindow ||
            (Tk_IsMapped(dispPtr->warpWindow) && Tk_WindowId(dispPtr->warpWindow) != None)) {
        TkpWarpPointer(dispPtr);
        XForceScreenSaver(dispPtr->display, ScreenSaverReset);
    }
        if (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;
        Tcl_Release(dispPtr->warpWindow);
        dispPtr->warpWindow = NULL;
    }
    dispPtr->flags &= ~TK_DISPLAY_IN_WARP;
}

/*
 *-------------------------------------------------------------------------
 *
 * GetVirtualEventUid --
 *
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
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







-
+













-
-
+
+







    				 * 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. */
    EventMask *maskPtr)		/* *maskPtr is filled in with the event types on which this
    unsigned *maskPtr)		/* *maskPtr is filled in with the event types on which this
    				 * pattern sequence depends. */
{
    unsigned patsBufSize = 1;
    unsigned numPats;
    unsigned totalCount = 0;
    int virtualFound = 0;
    const char *p = eventString;
    TkPattern *patPtr;
    PatSeq *psPtr;
    Tcl_HashEntry *hPtr;
    int isNew;
    unsigned count;
    unsigned maxCount = 0;
    EventMask eventMask = 0;
    ModMask modMask = 0;
    unsigned eventMask = 0;
    unsigned modMask = 0;
    PatternTableKey key;

    assert(lookupTables);
    assert(eventString);

    psPtr = (PatSeq *)ckalloc(PATSEQ_MEMSIZE(patsBufSize));

4821
4822
4823
4824
4825
4826
4827
4828

4829
4830
4831

4832
4833
4834
4835
4836
4837
4838
4842
4843
4844
4845
4846
4847
4848

4849
4850
4851

4852
4853
4854
4855
4856
4857
4858
4859







-
+


-
+








static unsigned
ParseEventDescription(
    Tcl_Interp *interp,		/* For error messages. */
    const char **eventStringPtr,/* On input, holds a pointer to start of event string. On exit,
    				 * gets pointer to rest of string after parsed event. */
    TkPattern *patPtr,		/* Filled with the pattern parsed from the event string. */
    EventMask *eventMaskPtr)	/* Filled with event mask of matched event. */
    unsigned *eventMaskPtr)	/* Filled with event mask of matched event. */
{
    const char *p;
    EventMask eventMask = 0;
    unsigned eventMask = 0;
    unsigned count = 1;

    assert(eventStringPtr);
    assert(patPtr);
    assert(eventMaskPtr);

    p = *eventStringPtr;
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
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







-
+









-
+







			return FinalizeParseEventDescription(
				interp,
				patPtr, 0,
				Tcl_ObjPrintf("specified button \"%s\" for non-button event", field),
				"NON_BUTTON");
		    }
#if SUPPORT_ADDITIONAL_MOTION_SYNTAX
		    patPtr->modMask |= TkGetButtonMask(button);
		    patPtr->modMask |= Tk_GetButtonMask(button);
		    p = SkipFieldDelims(p);
		    while (*p && *p != '>') {
			p = SkipFieldDelims(GetField(p, field, sizeof(field)));
			if ((button = GetButtonNumber(field)) == 0) {
			    return FinalizeParseEventDescription(
				    interp,
				    patPtr, 0,
				    Tcl_ObjPrintf("bad button number \"%s\"", field), "BUTTON");
			}
			patPtr->modMask |= TkGetButtonMask(button);
			patPtr->modMask |= Tk_GetButtonMask(button);
		    }
		    patPtr->info = ButtonNumberFromState(patPtr->modMask);
#endif
		} else {
		    return FinalizeParseEventDescription(
			    interp,
			    patPtr, 0,
5137
5138
5139
5140
5141
5142
5143
5144

5145
5146
5147
5148
5149
5150
5151
5158
5159
5160
5161
5162
5163
5164

5165
5166
5167
5168
5169
5170
5171
5172







-
+







		&& patPtr->info != ' ') {
	    char c = (char) patPtr->info;
	    Tcl_AppendToObj(patternObj, &c, 1);
	} else if (patPtr->eventType == VirtualEvent) {
	    assert(patPtr->name);
	    Tcl_AppendPrintfToObj(patternObj, "<<%s>>", patPtr->name);
	} else {
	    ModMask modMask;
	    unsigned modMask;
	    const ModInfo *modPtr;

	    /*
	     * It's a more general event specification. First check for "Double",
	     * "Triple", "Quadruple", then modifiers, then event type, then keysym
	     * or button detail.
	     */
5185
5186
5187
5188
5189
5190
5191
5192
5193


5194
5195
5196
5197

5198
5199
5200
5201



5202
5203
5204
5205
5206
5207
5208
5206
5207
5208
5209
5210
5211
5212


5213
5214
5215
5216
5217

5218
5219



5220
5221
5222
5223
5224
5225
5226
5227
5228
5229







-
-
+
+



-
+

-
-
-
+
+
+







			Tcl_AppendToObj(patternObj, "-", 1);
			Tcl_AppendToObj(patternObj, string, -1);
		    }
		    break;
		}
		case ButtonPress:
		case ButtonRelease:
		    assert(patPtr->info <= Button9);
		    Tcl_AppendPrintfToObj(patternObj, "-%d", (int) patPtr->info);
		    assert(patPtr->info <= 13);
		    Tcl_AppendPrintfToObj(patternObj, "-%u", (unsigned) ((patPtr->info > 7) ? (patPtr->info - 4) : patPtr->info));
		    break;
#if PRINT_SHORT_MOTION_SYNTAX
		case MotionNotify: {
		    ModMask mask = patPtr->modMask;
		    unsigned mask = patPtr->modMask;
		    while (mask & ALL_BUTTONS) {
			int button = ButtonNumberFromState(mask);
			Tcl_AppendPrintfToObj(patternObj, "-%d", button);
			mask &= ~TkGetButtonMask(button);
			unsigned button = ButtonNumberFromState(mask);
			Tcl_AppendPrintfToObj(patternObj, "-%u", (button > 7) ? (button - 4) : button);
			mask &= ~Tk_GetButtonMask(button);
		    }
		    break;
		}
#endif
		}
	    }

5231
5232
5233
5234
5235
5236
5237
5238



5239

































5240
5241
5242
5243

5244
5245

5246
5247
5248
5249
5250
5251
5252
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







-
+
+
+

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



-
+
-
-
+







 */

KeySym
TkStringToKeysym(
    const char *name)		/* Name of a keysym. */
{
#ifdef REDO_KEYSYM_LOOKUP
    Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&keySymTable, name);
    Tcl_HashEntry *hPtr;
#endif /* REDO_KEYSYM_LOOKUP */
    int keysym;

    size_t len = TkUtfToUniChar(name, &keysym);
    if (name[len] == '\0') {
        if (!Tcl_UniCharIsPrint(keysym)) {
    	/* This form not supported */
        } else if ((unsigned)(keysym - 0x21) <= 0x5D) {
		return keysym;
	    } else if ((unsigned)(keysym - 0xA1) <= 0x5E) {
		return keysym;
	    } else if (keysym == 0x20AC) {
		return 0x20AC;
	    } else {
		return keysym + 0x1000000;
	    }
    }
#ifdef REDO_KEYSYM_LOOKUP
    if ((name[0] == 'U') && ((unsigned)(name[1] - '0') <= 9)) {
	char *p = (char *)name + 1;
	keysym = strtol(p, &p, 16);
	if ((p >= name + 5) && (p <= name + 9) && !*p && (keysym >= 0x20)
		&& ((unsigned)(keysym - 0x7F) > 0x20)) {
	    if ((unsigned)(keysym - 0x21) <= 0x5D) {
		return keysym;
	    } else if ((unsigned)(keysym - 0xA1) <= 0x5E) {
		return keysym;
	    } else if (keysym == 0x20AC) {
		return keysym;
	    }
	    return keysym + 0x1000000;
	}
    }
#endif
#ifdef REDO_KEYSYM_LOOKUP
    hPtr = Tcl_FindHashEntry(&keySymTable, name);
    if (hPtr) {
	return (KeySym) Tcl_GetHashValue(hPtr);
    }
    assert(name);
    if (((unsigned)(name[0]-1) < 0x7F) && !name[1]) {
    if (strlen(name) == 1u) {
	KeySym keysym = (KeySym) (unsigned char) name[0];
	keysym = (unsigned char) name[0];

	if (TkKeysymToString(keysym)) {
	    return keysym;
	}
    }
#endif /* REDO_KEYSYM_LOOKUP */
    assert(name);
5271
5272
5273
5274
5275
5276
5277
5278

























5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
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







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






-
-
-







 */

const char *
TkKeysymToString(
    KeySym keysym)
{
#ifdef REDO_KEYSYM_LOOKUP
    Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&nameTable, (char *)keysym);
    Tcl_HashEntry *hPtr;
#endif

    if ((unsigned)(keysym - 0x21) <= 0x5D) {
	keysym += 0x1000000;
    } else if ((unsigned)(keysym - 0xA1) <= 0x5E) {
	keysym += 0x1000000;
    } else if (keysym == 0x20AC) {
	keysym += 0x1000000;
    }
    if ((keysym >= 0x1000020) && (keysym <= 0x110FFFF)
	    && ((unsigned)(keysym - 0x100007F) > 0x20)) {
	char buf[10];
	if (Tcl_UniCharIsPrint(keysym-0x1000000)) {
	    buf[TkUniCharToUtf(keysym - 0x1000000, buf)] = '\0';
	} else if (keysym >= 0x1010000) {
	    sprintf(buf, "U%08X", (int)(keysym - 0x1000000));
	} else {
	    sprintf(buf, "U%04X", (int)(keysym - 0x1000000));
	}
	return Tk_GetUid(buf);
    }

#ifdef REDO_KEYSYM_LOOKUP
    hPtr = Tcl_FindHashEntry(&nameTable, INT2PTR(keysym));

    if (hPtr) {
	return (const char *)Tcl_GetHashValue(hPtr);
    }
#endif /* REDO_KEYSYM_LOOKUP */

    if (keysym > (KeySym)0x1008FFFF) {
	return NULL;
    }
    return XKeysymToString(keysym);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetBindingXEvent --
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
5388
5389
5390
5391
5392
5393
5394





























5395
5396
5397
5398
5399
5400
5401







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







    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.

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







-
-
+
+







/*
 * tkBitmap.c --
 *
 *	This file maintains a database of read-only bitmaps for the Tk
 *	toolkit. This allows bitmaps to be shared between widgets and also
 *	avoids interactions with the X server.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1998 Sun Microsystems, Inc.
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1998 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

Changes to generic/tkBusy.c.

121
122
123
124
125
126
127
128

129
130
131
132
133
134
135
136
137
138
121
122
123
124
125
126
127

128
129
130

131
132
133
134
135
136
137







-
+


-







 *
 *----------------------------------------------------------------------
 */

static void
BusyCustodyProc(
    ClientData clientData,	/* Information about the busy window. */
    Tk_Window tkwin)		/* Not used. */
    TCL_UNUSED(Tk_Window))		/* Not used. */
{
    Busy *busyPtr = (Busy *)clientData;
    (void)tkwin;

    Tk_DeleteEventHandler(busyPtr->tkBusy, StructureNotifyMask, BusyEventProc,
	    busyPtr);
    TkpHideBusyWindow(busyPtr);
    busyPtr->tkBusy = NULL;
    Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy);
}
154
155
156
157
158
159
160
161

162
163

164
165
166
167
168
169
170
171
172
173
174
175
153
154
155
156
157
158
159

160
161

162
163
164



165
166
167
168
169
170
171







-
+

-
+


-
-
-







 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
BusyGeometryProc(
    ClientData dummy,	/* Information about window that got new
    TCL_UNUSED(void *),	/* Information about window that got new
				 * preferred geometry. */
    Tk_Window tkwin)		/* Other Tk-related information about the
    TCL_UNUSED(Tk_Window))		/* Other Tk-related information about the
				 * window. */
{
    (void)dummy;
    (void)tkwin;

    /* Should never get here */
}

/*
 *----------------------------------------------------------------------
 *
 * DoConfigureNotify --
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
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







-
+









-
+







    };
    enum options {
	BUSY_BUSYWINDOW, BUSY_CGET, BUSY_CONFIGURE, BUSY_CURRENT, BUSY_FORGET,
	BUSY_HOLD, BUSY_STATUS
    };

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "options ?arg arg ...?");
	Tcl_WrongNumArgs(interp, 1, objv, "options ?arg ...?");
	return TCL_ERROR;
    }

    /*
     * [tk busy <window>] command shortcut.
     */

    if (Tcl_GetString(objv[1])[0] == '.') {
	if (objc%2 == 1) {
	    Tcl_WrongNumArgs(interp, 1, objv, "window ?option value ...?");
	    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) {
861
862
863
864
865
866
867
868

869
870
871
872
873
874
875
857
858
859
860
861
862
863

864
865
866
867
868
869
870
871







-
+







	    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);
896
897
898
899
900
901
902
903

904
905
906
907
908
909
910
892
893
894
895
896
897
898

899
900
901
902
903
904
905
906







-
+







	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,
			TkNewWindowObj(busyPtr->tkRef));
			Tk_NewWindowObj(busyPtr->tkRef));
	    }
	}
	Tcl_SetObjResult(interp, objPtr);
	return TCL_OK;
    }

    case BUSY_FORGET:
918
919
920
921
922
923
924
925

926
927
928
929
930
931
932
914
915
916
917
918
919
920

921
922
923
924
925
926
927
928







-
+







	}
	TkpHideBusyWindow(busyPtr);
	Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy);
	return TCL_OK;

    case BUSY_HOLD:
	if (objc < 3 || objc%2 != 1) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?option value ...?");
	    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.

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







-
-
+
+







/*
 * tkButton.c --
 *
 *	This module implements a collection of button-like widgets for the Tk
 *	toolkit. The widgets implemented include buttons, checkbuttons,
 *	radiobuttons, and labels.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1998 Sun Microsystems, Inc.
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1998 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkButton.h"
756
757
758
759
760
761
762
763

764
765
766
767
768
769
770
756
757
758
759
760
761
762

763
764
765
766
767
768
769
770







-
+







	return TCL_ERROR;
    }
    if (ConfigureButton(interp, butPtr, objc - 2, objv + 2) != TCL_OK) {
	Tk_DestroyWindow(butPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, TkNewWindowObj(butPtr->tkwin));
    Tcl_SetObjResult(interp, Tk_NewWindowObj(butPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ButtonWidgetCmd --

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

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





-
-
+
+







/*
 * tkCanvArc.c --
 *
 *	This file implements arc items for canvas widgets.
 *
 * Copyright (c) 1992-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1992-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkCanvas.h"
703
704
705
706
707
708
709
710

711
712
713
714

715
716
717
718
719
720
721
722
703
704
705
706
707
708
709

710
711
712
713

714

715
716
717
718
719
720
721







-
+



-
+
-







 *	Resources associated with itemPtr are released.
 *
 *--------------------------------------------------------------
 */

static void
DeleteArc(
    Tk_Canvas canvas,		/* Info about overall canvas. */
    TCL_UNUSED(Tk_Canvas),		/* Info about overall canvas. */
    Tk_Item *itemPtr,		/* Item that is being deleted. */
    Display *display)		/* Display containing window for canvas. */
{
    ArcItem *arcPtr = (ArcItem *) itemPtr;
    ArcItem *arcPtr = (ArcItem *)itemPtr;
    (void)canvas;

    Tk_DeleteOutline(display, &(arcPtr->outline));
    if (arcPtr->numOutlinePoints != 0) {
	ckfree(arcPtr->outlinePtr);
    }
    if (arcPtr->fillColor != NULL) {
	Tk_FreeColor(arcPtr->fillColor);
790
791
792
793
794
795
796
797

798
799
800
801
802
803

804
805
806
807
808
809
810
789
790
791
792
793
794
795

796
797
798
799
800
801

802
803
804
805
806
807
808
809







-
+





-
+







    }

    /*
     * Make sure that the first coordinates are the lowest ones.
     */

    if (arcPtr->bbox[1] > arcPtr->bbox[3]) {
	double tmp = arcPtr->bbox[3];
	tmp = arcPtr->bbox[3];

	arcPtr->bbox[3] = arcPtr->bbox[1];
	arcPtr->bbox[1] = tmp;
    }
    if (arcPtr->bbox[0] > arcPtr->bbox[2]) {
	double tmp = arcPtr->bbox[2];
	tmp = arcPtr->bbox[2];

	arcPtr->bbox[2] = arcPtr->bbox[0];
	arcPtr->bbox[0] = tmp;
    }

    ComputeArcOutline(canvas,arcPtr);

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







-
-
+
+
+
+







-
-
-
-








static void
DisplayArc(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    Tk_Item *itemPtr,		/* Item to be displayed. */
    Display *display,		/* Display on which to draw item. */
    Drawable drawable,		/* Pixmap or window in which to draw item. */
    int x, int y,		/* Describes region of canvas that must be */
    int width, int height)	/* redisplayed (not used). */
    TCL_UNUSED(int),		/* Describes region of canvas that must be */
    TCL_UNUSED(int),	/* redisplayed (not used). */
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{
    ArcItem *arcPtr = (ArcItem *) itemPtr;
    short x1, y1, x2, y2;
    int start, extent, dashnumber;
    double lineWidth;
    Tk_State state = itemPtr->state;
    Pixmap stipple;
    (void)x;
    (void)y;
    (void)width;
    (void)height;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    lineWidth = arcPtr->outline.width;
    if (lineWidth < 1.0) {
	lineWidth = 1.0;
1644
1645
1646
1647
1648
1649
1650
1651

1652
1653
1654
1655
1656
1657
1658
1641
1642
1643
1644
1645
1646
1647

1648
1649
1650
1651
1652
1653
1654
1655







-
+







    }

    /*
     * First compute the two points that lie at the centers of the ends of the
     * curved arc segment, which are marked with X's in the figure below:
     *
     *
     *				  * * *
     *			          * * *
     *			      *          *
     *			   *      * *      *
     *			 *    *         *    *
     *			*   *             *   *
     *			 X *               * X
     *
     * The code is tricky because the arc can be ovular in shape. It computes
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
1994
1995
1996
1997
1998
1999
2000

2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013

2014
2015
2016
2017
2018
2019
2020







-
+












-







 */

static int
ArcToPostscript(
    Tcl_Interp *interp,		/* Leave Postscript or error message here. */
    Tk_Canvas canvas,		/* Information about overall canvas. */
    Tk_Item *itemPtr,		/* Item for which Postscript is wanted. */
    int prepass)		/* 1 means this is a prepass to collect font
    TCL_UNUSED(int))		/* 1 means this is a prepass to collect font
				 * information; 0 means final Postscript is
				 * being created. */
{
    ArcItem *arcPtr = (ArcItem *) itemPtr;
    double y1, y2, ang1, ang2;
    XColor *color;
    Pixmap stipple;
    XColor *fillColor;
    Pixmap fillStipple;
    Tk_State state = itemPtr->state;
    Tcl_Obj *psObj;
    Tcl_InterpState interpState;
    (void)prepass;

    y1 = Tk_CanvasPsY(canvas, arcPtr->bbox[1]);
    y2 = Tk_CanvasPsY(canvas, arcPtr->bbox[3]);
    ang1 = arcPtr->start;
    ang2 = ang1 + arcPtr->extent;
    if (ang2 < ang1) {
	ang1 = ang2;
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
2189
2190
2191
2192
2193
2194
2195

2196
2197

2198
2199
2200
2201
2202
2203
2204
2205


2206
2207
2208
2209
2210
2211
2212







-
+

-
+







-
-







 *	value argument.
 *
 *--------------------------------------------------------------
 */

static int
StyleParseProc(
    ClientData dummy,	/* some flags.*/
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Used for reporting errors. */
    Tk_Window tkwin,		/* Window containing canvas widget. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset)			/* Offset into item. */
{
    int c;
    size_t length;
    Style *stylePtr = (Style *) (widgRec + offset);
    (void)dummy;
    (void)tkwin;

    if (value == NULL || *value == 0) {
	*stylePtr = PIESLICE_STYLE;
	return TCL_OK;
    }

    c = value[0];
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
2252
2253
2254
2255
2256
2257
2258


2259
2260
2261
2262

2263
2264
2265
2266
2267



2268
2269
2270
2271
2272
2273
2274







-
-
+
+


-
+




-
-
-







 *	None.
 *
 *--------------------------------------------------------------
 */

static const char *
StylePrintProc(
    ClientData dummy,	/* Ignored. */
    Tk_Window tkwin,		/* Ignored. */
    TCL_UNUSED(void *),	/* Ignored. */
    TCL_UNUSED(Tk_Window),		/* Ignored. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset,			/* Offset into item. */
    Tcl_FreeProc **freeProcPtr)	/* Pointer to variable to fill in with
    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);
    (void)dummy;
    (void)tkwin;
    (void)freeProcPtr;

    if (*stylePtr == ARC_STYLE) {
	return "arc";
    } else if (*stylePtr == CHORD_STYLE) {
	return "chord";
    } else {
	return "pieslice";

Changes to generic/tkCanvBmap.c.

1
2
3
4
5
6
7


8
9
10
11
12
13
14
1
2
3
4
5


6
7
8
9
10
11
12
13
14





-
-
+
+







/*
 * tkCanvBmap.c --
 *
 *	This file implements bitmap items for canvas widgets.
 *
 * Copyright (c) 1992-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1992-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkCanvas.h"

Changes to generic/tkCanvImg.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





-
-
+
+







/*
 * tkCanvImg.c --
 *
 *	This file implements image items for canvas widgets.
 *
 * Copyright (c) 1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkCanvas.h"

Changes to generic/tkCanvLine.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





-
-
-
+
+
+







/*
 * 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 © 1991-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 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"
601
602
603
604
605
606
607
608

609
610
611
612
613
614
615
616
617
618
619
620
601
602
603
604
605
606
607

608
609
610
611
612

613
614
615
616
617
618
619







-
+




-







 *	Resources associated with itemPtr are released.
 *
 *--------------------------------------------------------------
 */

static void
DeleteLine(
    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. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    (void)canvas;

    Tk_DeleteOutline(display, &linePtr->outline);
    if (linePtr->coordPtr != NULL) {
	ckfree(linePtr->coordPtr);
    }
    if (linePtr->arrowGC != NULL) {
	Tk_FreeGC(display, linePtr->arrowGC);
706
707
708
709
710
711
712
713

714
715
716
717
718
719
720
705
706
707
708
709
710
711

712
713
714
715
716
717
718
719







-
+







	if (linePtr->arrow != ARROWS_FIRST) {
	    TkIncludePoint((Tk_Item *) linePtr, linePtr->lastArrowPtr);
	}
    }

    tsoffset = &linePtr->outline.tsoffset;
    if (tsoffset->flags & TK_OFFSET_INDEX) {
	double *coordPtr = linePtr->coordPtr
	coordPtr = linePtr->coordPtr
		+ (tsoffset->flags & ~TK_OFFSET_INDEX);

	if (tsoffset->flags <= 0) {
	    coordPtr = linePtr->coordPtr;
	    if ((linePtr->arrow == ARROWS_FIRST)
		    || (linePtr->arrow == ARROWS_BOTH)) {
		coordPtr = linePtr->firstArrowPtr;
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







-
-
-
+
+
+
+

-
+





-
-
-
-








static void
DisplayLine(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    Tk_Item *itemPtr,		/* Item to be displayed. */
    Display *display,		/* Display on which to draw item. */
    Drawable drawable,		/* Pixmap or window in which to draw item. */
    int x, int y, int width, int height)
				/* Describes region of canvas that must be
				 * redisplayed (not used). */
    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;
    (void)x;
    (void)y;
    (void)width;
    (void)height;

    if (!linePtr->numPoints || (linePtr->outline.gc == NULL)) {
	return;
    }

    if (state == TK_STATE_NULL) {
	    state = Canvas(canvas)->canvas_state;
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1693
1694
1695
1696
1697
1698
1699


1700
1701
1702
1703
1704
1705
1706







-
-







    if (linePtr->firstArrowPtr != NULL) {
	linePtr->coordPtr[0] = linePtr->firstArrowPtr[0];
	linePtr->coordPtr[1] = linePtr->firstArrowPtr[1];
	ckfree(linePtr->firstArrowPtr);
	linePtr->firstArrowPtr = NULL;
    }
    if (linePtr->lastArrowPtr != NULL) {
	int i;

	i = 2*(linePtr->numPoints-1);
	linePtr->coordPtr[i] = linePtr->lastArrowPtr[0];
	linePtr->coordPtr[i+1] = linePtr->lastArrowPtr[1];
	ckfree(linePtr->lastArrowPtr);
	linePtr->lastArrowPtr = NULL;
    }
    for (i = 0, coordPtr = linePtr->coordPtr; i < linePtr->numPoints;
1762
1763
1764
1765
1766
1767
1768
1769

1770
1771
1772
1773
1774
1775
1776
1756
1757
1758
1759
1760
1761
1762

1763
1764
1765
1766
1767
1768
1769
1770







-
+







	} else {
	    idx &= (TkSizeT)-2;	/* If index is odd, make it even. */
	}
	*indexPtr = idx;
	return TCL_OK;
    }

    string = TkGetStringFromObj(obj, &length);
    string = Tcl_GetStringFromObj(obj, &length);

    if (string[0] == '@') {
	int i;
	double x, y, bestDist, dist, *coordPtr;
	char *end;
	const char *p;

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







-
+

-
+










-
-







 *	Arrow information in recordPtr is updated.
 *
 *--------------------------------------------------------------
 */

static int
ParseArrowShape(
    ClientData dummy,	/* Not used. */
    TCL_UNUSED(void *),	/* Not used. */
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Window tkwin,		/* Not used. */
    TCL_UNUSED(Tk_Window),		/* Not used. */
    const char *value,		/* Textual specification of arrow shape. */
    char *recordPtr,		/* Pointer to item record in which to store
				 * arrow information. */
    TkSizeT offset)			/* Offset of shape information in widget
				 * record. */
{
    LineItem *linePtr = (LineItem *) recordPtr;
    double a, b, c;
    int argc;
    const char **argv = NULL;
    (void)dummy;
    (void)tkwin;

    if ((size_t)offset != offsetof(LineItem, arrowShapeA)) {
	Tcl_Panic("ParseArrowShape received bogus offset");
    }

    if (Tcl_SplitList(interp, (char *) value, &argc, &argv) != TCL_OK) {
	goto syntaxError;
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
1989
1990
1991
1992
1993
1994
1995


1996
1997
1998
1999

2000
2001
2002
2003
2004
2005



2006
2007
2008
2009
2010
2011
2012







-
-
+
+


-
+





-
-
-







 *	None.
 *
 *--------------------------------------------------------------
 */

static const char *
PrintArrowShape(
    ClientData dummy,	/* Not used. */
    Tk_Window tkwin,		/* Window associated with linePtr's widget. */
    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. */
    TkSizeT offset,			/* Offset of arrow information in record. */
    TCL_UNUSED(TkSizeT),			/* Offset of arrow information in record. */
    Tcl_FreeProc **freeProcPtr)	/* Store address of function to call to free
				 * string here. */
{
    LineItem *linePtr = (LineItem *) recordPtr;
    char *buffer = (char *)ckalloc(120);
    (void)dummy;
    (void)tkwin;
    (void)offset;

    sprintf(buffer, "%.5g %.5g %.5g", linePtr->arrowShapeA,
	    linePtr->arrowShapeB, linePtr->arrowShapeC);
    *freeProcPtr = TCL_DYNAMIC;
    return buffer;
}

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
2026
2027
2028
2029
2030
2031
2032

2033
2034

2035
2036
2037
2038
2039
2040
2041
2042


2043
2044
2045
2046
2047
2048
2049







-
+

-
+







-
-







 *	value argument.
 *
 *--------------------------------------------------------------
 */

static int
ArrowParseProc(
    ClientData dummy,	/* some flags.*/
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Used for reporting errors. */
    Tk_Window tkwin,		/* Window containing canvas widget. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset)			/* Offset into item. */
{
    int c;
    size_t length;
    Arrows *arrowPtr = (Arrows *) (widgRec + offset);
    (void)dummy;
    (void)tkwin;

    if (value == NULL || *value == 0) {
	*arrowPtr = ARROWS_NONE;
	return TCL_OK;
    }

    c = value[0];
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
2093
2094
2095
2096
2097
2098
2099


2100
2101
2102
2103

2104
2105
2106
2107
2108



2109
2110
2111
2112
2113
2114
2115







-
-
+
+


-
+




-
-
-







 *	None.
 *
 *--------------------------------------------------------------
 */

static const char *
ArrowPrintProc(
    ClientData dummy,	/* Ignored. */
    Tk_Window tkwin,		/* Window containing canvas widget. */
    TCL_UNUSED(void *),	/* Ignored. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset,			/* Offset into item. */
    Tcl_FreeProc **freeProcPtr)	/* Pointer to variable to fill in with
    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);
    (void)dummy;
    (void)tkwin;
    (void)freeProcPtr;

    switch (*arrowPtr) {
    case ARROWS_FIRST:
	return "first";
    case ARROWS_LAST:
	return "last";
    case ARROWS_BOTH:
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
2296
2297
2298
2299
2300
2301
2302

2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314

2315
2316
2317
2318
2319
2320
2321







-
+











-







 */

static int
LineToPostscript(
    Tcl_Interp *interp,		/* Leave Postscript or error message here. */
    Tk_Canvas canvas,		/* Information about overall canvas. */
    Tk_Item *itemPtr,		/* Item for which Postscript is wanted. */
    int prepass)		/* 1 means this is a prepass to collect font
    TCL_UNUSED(int))		/* 1 means this is a prepass to collect font
				 * information; 0 means final Postscript is
				 * being created. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    int style;
    double width;
    XColor *color;
    Pixmap stipple;
    Tk_State state = itemPtr->state;
    Tcl_Obj *psObj;
    Tcl_InterpState interpState;
    (void)prepass;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    width = linePtr->outline.width;
    color = linePtr->outline.color;

Changes to generic/tkCanvPoly.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





-
-
-
+
+
+







/*
 * tkCanvPoly.c --
 *
 *	This file implements polygon items for canvas widgets.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-2000 Ajuba Solutions.
 * Copyright © 1991-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1998-2000 Ajuba Solutions.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkCanvas.h"
872
873
874
875
876
877
878
879
880


881
882
883
884
885
886
887
888
889
890
891
872
873
874
875
876
877
878


879
880
881
882


883
884
885
886
887
888
889







-
-
+
+


-
-








static void
DisplayPolygon(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    Tk_Item *itemPtr,		/* Item to be displayed. */
    Display *display,		/* Display on which to draw item. */
    Drawable drawable,		/* Pixmap or window in which to draw item. */
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),	/* Describes region of canvas that must be */
    TCL_UNUSED(int),	/* redisplayed (not used). */
    TCL_UNUSED(int),
    TCL_UNUSED(int))
				/* Describes region of canvas that must be
				 * redisplayed (not used). */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    Tk_State state = itemPtr->state;
    Pixmap stipple = polyPtr->fillStipple;
    double linewidth = polyPtr->outline.width;

    if (((polyPtr->fillGC == NULL) && (polyPtr->outline.gc == NULL)) ||
1688
1689
1690
1691
1692
1693
1694
1695

1696
1697
1698
1699
1700
1701
1702
1686
1687
1688
1689
1690
1691
1692

1693
1694
1695
1696
1697
1698
1699
1700







-
+







	} else {
	    idx = (idx & (TkSizeT)-2) % count;
	}
	*indexPtr = idx;
	return TCL_OK;
    }

    string = TkGetStringFromObj(obj, &length);
    string = Tcl_GetStringFromObj(obj, &length);

    if (string[0] == '@') {
	int i;
	double x, y, bestDist, dist, *coordPtr;
	char *end;
	const char *p;

Changes to generic/tkCanvPs.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







-
-
+
+







/*
 * tkCanvPs.c --
 *
 *	This module provides Postscript output support for canvases, including
 *	the "postscript" widget command plus a few utility functions used for
 *	generating Postscript.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1991-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkCanvas.h"
1599
1600
1601
1602
1603
1604
1605
1606

1607
1608
1609
1610
1611
1612
1613
1599
1600
1601
1602
1603
1604
1605

1606
1607
1608
1609
1610
1611
1612
1613







-
+








    for (yy = 0, lineLen=0; yy < height; yy++) {
	switch (colorLevel) {
	case 0: {
	    /*
	     * Generate data for image in monochrome mode. No attempt at
	     * dithering is made--instead, just set a threshold. To handle
	     * transparecies we need to output two lines: one for the black
	     * transparencies we need to output two lines: one for the black
	     * pixels, one for the white ones.
	     */

	    unsigned char mask = 0x80;
	    unsigned char data = 0x00;

	    for (xx = 0; xx< width; xx ++) {

Changes to generic/tkCanvText.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





-
-
+
+







/*
 * tkCanvText.c --
 *
 *	This file implements text items for canvas widgets.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1991-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkCanvas.h"
1016
1017
1018
1019
1020
1021
1022
1023

1024
1025
1026
1027
1028
1029
1030
1016
1017
1018
1019
1020
1021
1022

1023
1024
1025
1026
1027
1028
1029
1030







-
+







    TextItem *textPtr = (TextItem *) itemPtr;
    int byteIndex, charsAdded;
    TkSizeT 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) {
	index = 0;
    }
    if (index + 1 > textPtr->numChars + 1) {
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
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







-
+












-











-
+







 *
 *--------------------------------------------------------------
 */

static int
GetTextIndex(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing item. */
    TCL_UNUSED(Tk_Canvas),		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item for which the index is being
				 * specified. */
    Tcl_Obj *obj,		/* Specification of a particular character in
				 * itemPtr's text. */
    TkSizeT *indexPtr)		/* Where to store converted character
				 * index. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    TkSizeT length, idx;
    int c;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;
    const char *string;
    (void)canvas;

    if (TCL_OK == TkGetIntForIndex(obj, textPtr->numChars - 1, 1, &idx)) {
	if (idx == TCL_INDEX_NONE) {
	    idx = 0;
	} else if (idx > textPtr->numChars) {
	    idx = textPtr->numChars;
	}
	*indexPtr = idx;
	return TCL_OK;
    }

    string = TkGetStringFromObj(obj, &length);
    string = Tcl_GetStringFromObj(obj, &length);
    c = string[0];

    if ((c == 'i')
	    && (strncmp(string, "insert", length) == 0)) {
	*indexPtr = textPtr->insertPos;
    } else if ((c == 's') && (length >= 5)
	    && (strncmp(string, "sel.first", length) == 0)) {
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
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







-
+


















-
+







		    "selection isn't in item", -1));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "UNSELECTED", NULL);
	    return TCL_ERROR;
	}
	*indexPtr = textInfoPtr->selectLast;
    } else if (c == '@') {
	int x, y;
	double tmp, c = textPtr->cosine, s = textPtr->sine;
	double tmp, cs = textPtr->cosine, s = textPtr->sine;
	char *end;
	const char *p;

	p = string+1;
	tmp = strtod(p, &end);
	if ((end == p) || (*end != ',')) {
	    goto badIndex;
	}
	x = (int) ((tmp < 0) ? tmp - 0.5 : tmp + 0.5);
	p = end+1;
	tmp = strtod(p, &end);
	if ((end == p) || (*end != 0)) {
	    goto badIndex;
	}
	y = (int) ((tmp < 0) ? tmp - 0.5 : tmp + 0.5);
	x -= (int) textPtr->drawOrigin[0];
	y -= (int) textPtr->drawOrigin[1];
	*indexPtr = Tk_PointToChar(textPtr->textLayout,
		(int) (x*c - y*s), (int) (y*c + x*s));
		(int) (x*cs - y*s), (int) (y*cs + x*s));
    } else {
	/*
	 * Some of the paths here leave messages in the interp's result, so we
	 * have to clear it out before storing our own message.
	 */

    badIndex:
1474
1475
1476
1477
1478
1479
1480
1481

1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1473
1474
1475
1476
1477
1478
1479

1480
1481
1482
1483
1484
1485
1486

1487
1488
1489
1490
1491
1492
1493







-
+






-







 *	The cursor position will change.
 *
 *--------------------------------------------------------------
 */

static void
SetTextCursor(
    Tk_Canvas canvas,		/* Record describing canvas widget. */
    TCL_UNUSED(Tk_Canvas),		/* Record describing canvas widget. */
    Tk_Item *itemPtr,		/* Text item in which cursor position is to be
				 * set. */
    TkSizeT index)			/* Character index of character just before
				 * which cursor is to be positioned. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    (void)canvas;

    if (index == TCL_INDEX_NONE) {
	textPtr->insertPos = 0;
    } else if (index > textPtr->numChars) {
	textPtr->insertPos = textPtr->numChars;
    } else {
	textPtr->insertPos = index;
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
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







-
+













-







 *	None.
 *
 *--------------------------------------------------------------
 */

static TkSizeT
GetSelText(
    Tk_Canvas canvas,		/* Canvas containing selection. */
    TCL_UNUSED(Tk_Canvas),		/* Canvas containing selection. */
    Tk_Item *itemPtr,		/* Text item containing selection. */
    TkSizeT offset,			/* Byte offset within selection of first
				 * character to be returned. */
    char *buffer,		/* Location in which to place selection. */
    TkSizeT maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NULL
				 * character. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    TkSizeT byteCount;
    char *text;
    const char *selStart, *selEnd;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;
    (void)canvas;

    if (((int)textInfoPtr->selectFirst < 0) ||
	    (textInfoPtr->selectFirst + 1 > textInfoPtr->selectLast + 1)) {
	return 0;
    }
    text = textPtr->text;
    selStart = Tcl_UtfAtIndex(text, textInfoPtr->selectFirst);

Changes to generic/tkCanvUtil.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






-
+







/*
 * tkCanvUtil.c --
 *
 *	This file contains a collection of utility functions used by the
 *	implementations of various canvas item types.
 *
 * Copyright (c) 1994 Sun Microsystems, Inc.
 * Copyright © 1994 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkCanvas.h"
770
771
772
773
774
775
776
777

778
779
780
781
782
783
784
770
771
772
773
774
775
776

777
778
779
780
781
782
783
784







-
+







     */

    if (methods == NULL) {
	methods = InitSmoothMethods(interp);
    }

    /*
     * Backward compatability hack.
     * Backward compatibility hack.
     */

    if (strncmp(value, "bezier", length) == 0) {
	smooth = &tkBezierSmoothMethod;
    }

    /*

Changes to generic/tkCanvWind.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





-
-
+
+







/*
 * tkCanvWind.c --
 *
 *	This file implements window items for canvas widgets.
 *
 * Copyright (c) 1992-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1992-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkCanvas.h"
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







-
+







			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		TranslateWinItem(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double deltaX, double deltaY);
static int		WinItemCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    Tcl_Obj *const objv[]);
static void		WinItemLostSlaveProc(ClientData clientData,
static void		WinItemLostContentProc(ClientData clientData,
			    Tk_Window tkwin);
static void		WinItemRequestProc(ClientData clientData,
			    Tk_Window tkwin);
static void		WinItemStructureProc(ClientData clientData,
			    XEvent *eventPtr);
static int		WinItemToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
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







-
+







 * The structure below defines the official type record for the canvas (as
 * geometry manager):
 */

static const Tk_GeomMgr canvasGeomType = {
    "canvas",				/* name */
    WinItemRequestProc,			/* requestProc */
    WinItemLostSlaveProc,		/* lostSlaveProc */
    WinItemLostContentProc,		/* lostContentProc */
};

/*
 *--------------------------------------------------------------
 *
 * CreateWinItem --
 *
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
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







-
+


-
+





-
+





-
-
+
+

-
+







    DisplayWinItem(winItemPtr->canvas, (Tk_Item *) winItemPtr, NULL,
	    (Drawable) -1, 0, 0, 0, 0);
}

/*
 *--------------------------------------------------------------
 *
 * WinItemLostSlaveProc --
 * WinItemLostContentProc --
 *
 *	This function is invoked by Tk whenever some other geometry claims
 *	control over a slave that used to be managed by us.
 *	control over a content window that used to be managed by us.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Forgets all canvas-related information about the slave.
 *	Forgets all canvas-related information about the content window.
 *
 *--------------------------------------------------------------
 */

static void
WinItemLostSlaveProc(
    ClientData clientData,	/* WindowItem structure for slave window that
WinItemLostContentProc(
    ClientData clientData,	/* WindowItem structure for content window window that
				 * was stolen away. */
    Tk_Window tkwin)		/* Tk's handle for the slave window. */
    Tk_Window tkwin)		/* Tk's handle for the content window. */
{
    WindowItem *winItemPtr = (WindowItem *)clientData;
    Tk_Window canvasTkwin = Tk_CanvasTkwin(winItemPtr->canvas);
    (void)tkwin;

    Tk_DeleteEventHandler(winItemPtr->tkwin, StructureNotifyMask,
	    WinItemStructureProc, winItemPtr);

Changes to generic/tkCanvas.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







-
-
-
+
+
+







/*
 * 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 © 1991-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 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"
795
796
797
798
799
800
801
802

803
804
805
806
807
808
809
795
796
797
798
799
800
801

802
803
804
805
806
807
808
809







-
+







	    CanvasBindProc, canvasPtr);
    Tk_CreateSelHandler(canvasPtr->tkwin, XA_PRIMARY, XA_STRING,
	    CanvasFetchSelection, canvasPtr, XA_STRING);
    if (ConfigureCanvas(interp, canvasPtr, argc-2, argv+2, 0) != TCL_OK) {
	goto error;
    }

    Tcl_SetObjResult(interp, TkNewWindowObj(canvasPtr->tkwin));
    Tcl_SetObjResult(interp, Tk_NewWindowObj(canvasPtr->tkwin));
    return TCL_OK;

  error:
    Tk_DestroyWindow(canvasPtr->tkwin);
    return TCL_ERROR;
}

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
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







-
-
+
+











-
+
















-
-
+
+





-
+







    TkCanvas *canvasPtr = (TkCanvas *)clientData;
    int c, result;
    Tk_Item *itemPtr = NULL;	/* Initialization needed only to prevent
				 * compiler warning. */
    TagSearch *searchPtr = NULL;/* Allocated by first TagSearchScan, freed by
				 * TagSearchDestroy */

    int index;
    static const char *const optionStrings[] = {
    int idx;
    static const char *const canvasOptionStrings[] = {
	"addtag",	"bbox",		"bind",		"canvasx",
	"canvasy",	"cget",		"configure",	"coords",
	"create",	"dchars",	"delete",	"dtag",
	"find",		"focus",	"gettags",	"icursor",
        "image",	"imove",	"index",	"insert",
	"itemcget",	"itemconfigure",
	"lower",	"move",		"moveto",	"postscript",
	"raise",	"rchars",	"rotate",	"scale",
	"scan",		"select",	"type",		"xview",
	"yview",	NULL
    };
    enum options {
    enum canvasOptionStringsEnum {
	CANV_ADDTAG,	CANV_BBOX,	CANV_BIND,	CANV_CANVASX,
	CANV_CANVASY,	CANV_CGET,	CANV_CONFIGURE,	CANV_COORDS,
	CANV_CREATE,	CANV_DCHARS,	CANV_DELETE,	CANV_DTAG,
	CANV_FIND,	CANV_FOCUS,	CANV_GETTAGS,	CANV_ICURSOR,
        CANV_IMAGE,	CANV_IMOVE,	CANV_INDEX,	CANV_INSERT,
	CANV_ITEMCGET,	CANV_ITEMCONFIGURE,
	CANV_LOWER,	CANV_MOVE,	CANV_MOVETO,	CANV_POSTSCRIPT,
	CANV_RAISE,	CANV_RCHARS,	CANV_ROTATE,	CANV_SCALE,
	CANV_SCAN,	CANV_SELECT,	CANV_TYPE,	CANV_XVIEW,
	CANV_YVIEW
    };

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
    if (Tcl_GetIndexFromObj(interp, objv[1], canvasOptionStrings, "option", 0,
	    &idx) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_Preserve(canvasPtr);

    result = TCL_OK;
    switch ((enum options) index) {
    switch ((enum canvasOptionStringsEnum)idx) {
    case CANV_ADDTAG:
	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tag searchCommand ?arg ...?");
	    result = TCL_ERROR;
	    goto done;
	}
	result = FIND_ITEMS(objv[2], 3);
984
985
986
987
988
989
990
991

992
993
994
995
996
997
998
984
985
986
987
988
989
990

991
992
993
994
995
996
997
998







-
+








	if (canvasPtr->bindingTable == NULL) {
	    canvasPtr->bindingTable = Tk_CreateBindingTable(interp);
	}

	if (objc == 5) {
	    int append = 0;
	    unsigned long mask;
	    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;
	    }
1032
1033
1034
1035
1036
1037
1038
1039

1040
1041
1042
1043
1044
1045
1046
1032
1033
1034
1035
1036
1037
1038

1039
1040
1041
1042
1043
1044
1045
1046







-
+







	    }
	    mask = Tk_CreateBinding(interp, canvasPtr->bindingTable,
		    object, Tcl_GetString(objv[3]), argv4, append);
	    if (mask == 0) {
		result = TCL_ERROR;
		goto done;
	    }
	    if (mask & ~(unsigned long)(ButtonMotionMask|Button1MotionMask
	    if (mask & ~(ButtonMotionMask|Button1MotionMask
		    |Button2MotionMask|Button3MotionMask|Button4MotionMask
		    |Button5MotionMask|ButtonPressMask|ButtonReleaseMask
		    |EnterWindowMask|LeaveWindowMask|KeyPressMask
		    |KeyReleaseMask|PointerMotionMask|VirtualEventMask)) {
		Tk_DeleteBinding(interp, canvasPtr->bindingTable,
			object, Tcl_GetString(objv[3]));
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
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
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







-










-
+







    doneImove:
	Tcl_DecrRefCount(tmpObj);
	break;
    }
    case CANV_CREATE: {
	Tk_ItemType *typePtr;
	Tk_ItemType *matchPtr = NULL;
	Tk_Item *itemPtr;
	int isNew = 0;
	Tcl_HashEntry *entryPtr;
	const char *arg;
	TkSizeT length;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "type coords ?arg ...?");
	    result = TCL_ERROR;
	    goto done;
	}
	arg = TkGetStringFromObj(objv[2], &length);
	arg = Tcl_GetStringFromObj(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.
	 */
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1658
1659
1660
1661
1662
1663
1664

1665
1666
1667
1668
1669
1670
1671







-







	    }
	    if ((result != TCL_OK) || (objc < 5)) {
		break;
	    }
	}
	break;
    case CANV_LOWER: {
	Tk_Item *itemPtr;

	if ((objc != 3) && (objc != 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?belowThis?");
	    result = TCL_ERROR;
	    goto done;
	}

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







-
+

-
-
+
+







-
+







	    "mark", "dragto", NULL
	};

	if (objc < 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x y ?dragGain?");
	    result = TCL_ERROR;
	} else if (Tcl_GetIndexFromObj(interp, objv[2], optionStrings,
		"scan option", 0, &index) != TCL_OK) {
		"scan option", 0, &idx) != TCL_OK) {
	    result = TCL_ERROR;
	} else if ((objc != 5) && (objc != 5+index)) {
	    Tcl_WrongNumArgs(interp, 3, objv, index?"x y ?gain?":"x y");
	} else if ((objc != 5) && (objc != 5+idx)) {
	    Tcl_WrongNumArgs(interp, 3, objv, idx?"x y ?gain?":"x y");
	    result = TCL_ERROR;
	} else if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)){
	    result = TCL_ERROR;
	} else if ((objc == 6) &&
		(Tcl_GetIntFromObj(interp, objv[5], &gain) != TCL_OK)) {
	    result = TCL_ERROR;
	} else if (!index) {
	} else if (!idx) {
	    canvasPtr->scanX = x;
	    canvasPtr->scanXOrigin = canvasPtr->xOrigin;
	    canvasPtr->scanY = y;
	    canvasPtr->scanYOrigin = canvasPtr->yOrigin;
	} else {
	    int newXOrigin, newYOrigin, tmp;

2499
2500
2501
2502
2503
2504
2505
2506

2507
2508
2509
2510
2511
2512
2513
2497
2498
2499
2500
2501
2502
2503

2504
2505
2506
2507
2508
2509
2510
2511







-
+







 * Side effects:
*       None.
 *
 *----------------------------------------------------------------------
 */
static void
DecomposeMaskToShiftAndBits(
    unsigned long mask,     /* The pixel mask to examine */
    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;
2845
2846
2847
2848
2849
2850
2851
2852

2853
2854
2855
2856
2857
2858
2859
2843
2844
2845
2846
2847
2848
2849

2850
2851
2852
2853
2854
2855
2856
2857







-
+







    for (y = 0; y < blockPtr.height; ++y) {

#ifdef DEBUG_DRAWCANVAS
        Tcl_AppendResult(interp, " {", NULL);
#endif

        for(x = 0; x < blockPtr.width; ++x) {
            unsigned long pixel = 0;
            unsigned int pixel = 0;

            switch (ximagePtr->bits_per_pixel) {

                /*
                 * Get an 8 bit pixel from the XImage.
                 */

2877
2878
2879
2880
2881
2882
2883
2884

2885
2886
2887
2888
2889
2890
2891
2875
2876
2877
2878
2879
2880
2881

2882
2883
2884
2885
2886
2887
2888
2889







-
+








                /*
                 * Grab a 32 bit pixel from the XImage, and correct the
                 * byte order as necessary.
                 */

                case 32 :
                    pixel = *((unsigned long *)(ximagePtr->data + bytesPerPixel * x
                    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;
            }

3759
3760
3761
3762
3763
3764
3765
3766

3767
3768
3769
3770
3771
3772
3773
3757
3758
3759
3760
3761
3762
3763

3764
3765
3766
3767
3768
3769
3770
3771







-
+







	searchPtr->expr = NULL;

	/*
	 * Allocate buffer for rewritten tags (after de-escaping).
	 */

	searchPtr->rewritebufferAllocated = 100;
	searchPtr->rewritebuffer =(char *) ckalloc(searchPtr->rewritebufferAllocated);
	searchPtr->rewritebuffer = (char *)ckalloc(searchPtr->rewritebufferAllocated);
    }
    TagSearchExprInit(&searchPtr->expr);

    /*
     * How long is the tagOrId?
     */

4592
4593
4594
4595
4596
4597
4598
4599

4600
4601
4602
4603
4604
4605
4606
4590
4591
4592
4593
4594
4595
4596

4597
4598
4599
4600
4601
4602
4603
4604







-
+







     * 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));
	newTagPtr = (Tk_Uid *)ckalloc(itemPtr->tagSpace * sizeof(Tk_Uid));
	memcpy((void *) newTagPtr, itemPtr->tagPtr,
		itemPtr->numTags * sizeof(Tk_Uid));
	if (itemPtr->tagPtr != itemPtr->staticTagSpace) {
	    ckfree(itemPtr->tagPtr);
	}
	itemPtr->tagPtr = newTagPtr;
	tagPtr = &itemPtr->tagPtr[itemPtr->numTags];
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
5076
5077
5078
5079
5080
5081
5082

5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095

5096
5097
5098
5099
5100
5101
5102
5103







-
+












-
+








static void
CanvasBindProc(
    ClientData clientData,	/* Pointer to canvas structure. */
    XEvent *eventPtr)		/* Pointer to X event that just happened. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;
    unsigned long mask;
    unsigned mask;

    Tcl_Preserve(canvasPtr);

    /*
     * This code below keeps track of the current modifier state in
     * canvasPtr>state. This information is used to defer repicks of the
     * current item while buttons are down.
     */

    switch (eventPtr->type) {
    case ButtonPress:
    case ButtonRelease:
	mask = TkGetButtonMask(eventPtr->xbutton.button);
	mask = Tk_GetButtonMask(eventPtr->xbutton.button);

	/*
	 * For button press events, repick the current item using the button
	 * state before the event, then process the event. For button release
	 * events, first process the event, then repick the current item using
	 * the button state *after* the event (the button has logically gone
	 * up before we change the current item).
5174
5175
5176
5177
5178
5179
5180
5181

5182
5183
5184
5185
5186
5187
5188
5172
5173
5174
5175
5176
5177
5178

5179
5180
5181
5182
5183
5184
5185
5186







-
+







    TkCanvas *canvasPtr,	/* Canvas widget in which to select current
				 * item. */
    XEvent *eventPtr)		/* Event describing location of mouse cursor.
				 * Must be EnterWindow, LeaveWindow,
				 * ButtonRelease, or MotionNotify. */
{
    double coords[2];
    unsigned long buttonDown;
    unsigned int buttonDown;
    Tk_Item *prevItemPtr;
    SearchUids *searchUids = GetStaticUids();

    /*
     * Check whether or not a button is down. If so, we'll log entry and exit
     * into and out of the current item, but not entry into any other item.
     * This implements a form of grabbing equivalent to what the X server does

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 © 1991-1994 The Regents of the University of California.
 * Copyright © 1994-1995 Sun Microsystems, Inc.
 * Copyright © 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

Changes to generic/tkClipboard.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







-
-
+
+







/*
 * tkClipboard.c --
 *
 * 	This file manages the clipboard for the Tk toolkit, maintaining a
 * 	collection of data buffers that will be supplied on demand to
 * 	requesting applications.
 *
 * Copyright (c) 1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkSelect.h"
169
170
171
172
173
174
175
176
177


178
179
180

181
182
183
184
185
186
187
188
189
190
191
192
169
170
171
172
173
174
175


176
177
178
179

180
181




182
183
184
185
186
187
188







-
-
+
+


-
+

-
-
-
-







 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
ClipboardWindowHandler(
    ClientData dummy,	/* Not used. */
    TkSizeT offset,			/* Return selection bytes starting at this
    TCL_UNUSED(void *),	/* Not used. */
    TCL_UNUSED(TkSizeT),			/* Return selection bytes starting at this
				 * offset. */
    char *buffer,		/* Place to store converted selection. */
    TkSizeT maxBytes)		/* Maximum # of bytes to store at buffer. */
    TCL_UNUSED(TkSizeT))		/* Maximum # of bytes to store at buffer. */
{
    (void)dummy;
    (void)offset;
    (void)maxBytes;

    buffer[0] = '.';
    buffer[1] = 0;
    return 1;
}

/*
 *----------------------------------------------------------------------
454
455
456
457
458
459
460
461

462
463
464
465
466
467
468
450
451
452
453
454
455
456

457
458
459
460
461
462
463
464







-
+







	    "-displayof", "-format", "-type", NULL
	};
	enum appendOptions { APPEND_DISPLAYOF, APPEND_FORMAT, APPEND_TYPE };
	int subIndex;
	TkSizeT length;

	for (i = 2; i < objc - 1; i++) {
	    string = TkGetStringFromObj(objv[i], &length);
	    string = Tcl_GetStringFromObj(objv[i], &length);
	    if (string[0] != '-') {
		break;
	    }

	    /*
	     * If the argument is "--", it signifies the end of arguments.
	     */
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







-
+



-







 *	Sets up the clipWindow and related data structures.
 *
 *----------------------------------------------------------------------
 */

int
TkClipInit(
    Tcl_Interp *dummy,		/* Interpreter to use for error reporting. */
    TCL_UNUSED(Tcl_Interp *),		/* Interpreter to use for error reporting. */
    TkDisplay *dispPtr)/* Display to initialize. */
{
    XSetWindowAttributes atts;
    (void)dummy;

    dispPtr->clipTargetPtr = NULL;
    dispPtr->clipboardActive = 0;
    dispPtr->clipboardAppPtr = NULL;

    /*
     * Create the window used for clipboard ownership and selection retrieval,
706
707
708
709
710
711
712
713

714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
701
702
703
704
705
706
707

708
709
710
711


712
713
714
715
716
717
718
719
720
721
722







-
+



-
-











 *--------------------------------------------------------------
 */

static int
ClipboardGetProc(
    ClientData clientData,	/* Dynamic string holding partially assembled
				 * selection. */
    Tcl_Interp *dummy,		/* Interpreter used for error reporting (not
    TCL_UNUSED(Tcl_Interp *),		/* Interpreter used for error reporting (not
				 * used). */
    const char *portion)	/* New information to be appended. */
{
    (void)dummy;

    Tcl_DStringAppend((Tcl_DString *)clientData, portion, -1);
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkCmds.c.

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






-
-
-
+
+
+







/*
 * tkCmds.c --
 *
 *	This file contains a collection of Tk-related Tcl commands that didn't
 *	fit in any particular file of the toolkit.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 2000 Scriptics Corporation.
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 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"

893
894
895
896
897
898
899
900

901
902
903
904
905
906
907
908
909
910
911
912
913
893
894
895
896
897
898
899

900
901
902
903
904
905

906
907
908
909
910
911
912







-
+





-







    Tcl_SetObjResult(interp,
	    Tcl_NewBooleanObj(dispPtr->flags & TK_DISPLAY_USE_IM));
    return TCL_OK;
}

int
WindowingsystemCmd(
    ClientData dummy,	/* Main window associated with interpreter. */
    TCL_UNUSED(void *),	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    const char *windowingsystem;
    (void)dummy;

    if (objc != 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }
#if defined(_WIN32)
    windowingsystem = "win32";
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120




1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1109
1110
1111
1112
1113
1114
1115




1116
1117
1118
1119
1120
1121




1122
1123
1124
1125
1126
1127
1128







-
-
-
-
+
+
+
+


-
-
-
-








    return code;
}

static char *
WaitVariableProc(
    ClientData clientData,	/* Pointer to integer to set to 1. */
    Tcl_Interp *dummy,		/* Interpreter containing variable. */
    const char *name1,		/* Name of variable. */
    const char *name2,		/* Second part of variable name. */
    int flags)			/* Information about what happened. */
    TCL_UNUSED(Tcl_Interp *),		/* Interpreter containing variable. */
    TCL_UNUSED(const char *),		/* Name of variable. */
    TCL_UNUSED(const char *),		/* Second part of variable name. */
    TCL_UNUSED(int))			/* Information about what happened. */
{
    int *donePtr = (int *)clientData;
    (void)dummy;
    (void)name1;
    (void)name2;
    (void)flags;

    *donePtr = 1;
    return NULL;
}

static void
WaitVisibilityProc(
1170
1171
1172
1173
1174
1175
1176
1177

1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1165
1166
1167
1168
1169
1170
1171

1172
1173
1174
1175
1176
1177
1178
1179
1180

1181
1182
1183
1184
1185
1186
1187







-
+








-







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_UpdateObjCmd(
    ClientData dummy,	/* Main window associated with interpreter. */
    TCL_UNUSED(void *),	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const updateOptions[] = {"idletasks", NULL};
    int flags, index;
    TkDisplay *dispPtr;
    int code = TCL_OK;
    (void)dummy;

    if (objc == 1) {
	flags = TCL_DONT_WAIT;
    } else if (objc == 2) {
	if (Tcl_GetIndexFromObj(interp, objv[1], updateOptions, "option", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
1737
1738
1739
1740
1741
1742
1743











1744






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







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







	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window colorName");
	    return TCL_ERROR;
	}
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin) != TCL_OK) {
	    return TCL_ERROR;
	}
#ifdef TK_HAS_DYNAMIC_COLORS

	/*
	 * Make sure that the TkColor used for the winfo rgb command is
	 * destroyed when we are through with it, so we do not get stale RGB
	 * values next time.
	 */

	{
	    Colormap temp = Tk_Colormap(tkwin);
	    Tk_Colormap(tkwin) = TK_DYNAMIC_COLORMAP;
	colorPtr = Tk_GetColor(interp, tkwin, Tcl_GetString(objv[3]));
	    colorPtr = Tk_GetColor(interp, tkwin, Tcl_GetString(objv[3]));
	    Tk_Colormap(tkwin) = temp;
	}
#else
	colorPtr = Tk_GetColor(interp, tkwin, Tcl_GetString(objv[3]));
#endif
	if (colorPtr == NULL) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("%d %d %d",
		colorPtr->red, colorPtr->green, colorPtr->blue));
	Tk_FreeColor(colorPtr);
	break;
1848
1849
1850
1851
1852
1853
1854
1855

1856
1857
1858
1859
1860
1861
1862
1858
1859
1860
1861
1862
1863
1864

1865
1866
1867
1868
1869
1870
1871
1872







-
+







{
    const char *string;
    TkSizeT 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;
1886
1887
1888
1889
1890
1891
1892
1893

1894
1895

1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1896
1897
1898
1899
1900
1901
1902

1903
1904

1905
1906
1907



1908
1909
1910
1911
1912
1913
1914







-
+

-
+


-
-
-







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
TkDeadAppObjCmd(
    ClientData dummy,	/* Dummy. */
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    TCL_UNUSED(int),			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
	(void)dummy;
	(void)objc;

    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "can't invoke \"%s\" command: application has been destroyed",
	    Tcl_GetString(objv[0])));
    return TCL_ERROR;
}

/*

Changes to generic/tkColor.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







-
-
+
+







/*
 * tkColor.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-1997 Sun Microsystems, Inc.
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkColor.h"

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

Changes to generic/tkConfig.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






-
+







/*
 * tkConfig.c --
 *
 *	This file contains functions that manage configuration options for
 *	widgets and other things.
 *
 * Copyright (c) 1997-1998 Sun Microsystems, Inc.
 * Copyright © 1997-1998 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

/*
 * Temporary flag for working on new config package.
63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77







-
+







    Tcl_Obj *defaultPtr;	/* Default value for this option. */
    union {
	Tcl_Obj *monoColorPtr;	/* For color and border options, this is an
				 * alternate default value to use on
				 * monochrome displays. */
	struct TkOption *synonymPtr;
				/* For synonym options, this points to the
				 * master entry. */
				 * original entry. */
	const struct Tk_ObjCustomOption *custom;
				/* For TK_OPTION_CUSTOM. */
    } extra;
    int flags;			/* Miscellaneous flag values; see below for
				 * definitions. */
} Option;

233
234
235
236
237
238
239
240
241


242
243
244
245
246
247
248
233
234
235
236
237
238
239


240
241
242
243
244
245
246
247
248







-
-
+
+







	optionPtr->dbClassUID = NULL;
	optionPtr->defaultPtr = NULL;
	optionPtr->extra.monoColorPtr = NULL;
	optionPtr->flags = 0;

	if (specPtr->type == TK_OPTION_SYNONYM) {
	    /*
	     * This is a synonym option; find the master option that it refers
	     * to and create a pointer from the synonym to the master.
	     * This is a synonym option; find the original option that it refers
	     * to and create a pointer from the synonym to the origin.
	     */

	    for (specPtr2 = templatePtr, i = 0; ; specPtr2++, i++) {
		if (specPtr2->type == TK_OPTION_END) {
		    Tcl_Panic("Tk_CreateOptionTable couldn't find synonym");
		}
		if (strcmp(specPtr2->optionName,
659
660
661
662
663
664
665
666

667
668
669
670
671
672
673
659
660
661
662
663
664
665

666
667
668
669
670
671
672
673







-
+







	TkSizeT 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;
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1401
1402
1403
1404
1405
1406
1407


1408
1409
1410
1411
1412
1413
1414







-
-







	}
	if (specPtr->internalOffset != TCL_INDEX_NONE) {
	    char *ptr = (char *) &savePtr->items[i].internalForm;

	    CLANG_ASSERT(internalPtr);
	    switch (specPtr->type) {
	    case TK_OPTION_BOOLEAN:
		*((int *) internalPtr) = *((int *) ptr);
		break;
	    case TK_OPTION_INT:
		*((int *) internalPtr) = *((int *) ptr);
		break;
	    case TK_OPTION_DOUBLE:
		*((double *) internalPtr) = *((double *) ptr);
		break;
	    case TK_OPTION_STRING:
1495
1496
1497
1498
1499
1500
1501
1502
1503


1504
1505
1506
1507
1508
1509
1510
1511
1493
1494
1495
1496
1497
1498
1499


1500
1501

1502
1503
1504
1505
1506
1507
1508







-
-
+
+
-







    size_t count;
    Tk_SavedOption *savedOptionPtr;

    if (savePtr->nextPtr != NULL) {
	Tk_FreeSavedOptions(savePtr->nextPtr);
	ckfree(savePtr->nextPtr);
    }
    for (count = savePtr->numItems,
	    savedOptionPtr = &savePtr->items[savePtr->numItems-1];
    for (count = savePtr->numItems; count > 0; count--) {
	savedOptionPtr = &savePtr->items[count-1];
	    count > 0;  count--, savedOptionPtr--) {
	if (savedOptionPtr->optionPtr->flags & OPTION_NEEDS_FREEING) {
	    FreeResources(savedOptionPtr->optionPtr, savedOptionPtr->valuePtr,
		    (char *) &savedOptionPtr->internalForm, savePtr->tkwin);
	}
	if (savedOptionPtr->valuePtr != NULL) {
	    Tcl_DecrRefCount(savedOptionPtr->valuePtr);
	}
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
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







-

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

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

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

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

-
-
+
+

-
-
-
-
-
+
+
+
+
+

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

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

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

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







				 * *recordPtr. */
    Tk_Window tkwin)		/* Window corresponding to recordPtr. */
{
    Tcl_Obj *objPtr;
    void *internalPtr;		/* Points to internal value of option in
				 * record. */

    internalPtr = (char *)recordPtr + optionPtr->specPtr->internalOffset;
    objPtr = NULL;
    if (optionPtr->specPtr->internalOffset != TCL_INDEX_NONE) {
	internalPtr = (char *)recordPtr + optionPtr->specPtr->internalOffset;
    switch (optionPtr->specPtr->type) {
    case TK_OPTION_BOOLEAN:
	switch (optionPtr->specPtr->type) {
	case TK_OPTION_BOOLEAN:
	objPtr = Tcl_NewWideIntObj(*((int *) internalPtr));
	break;
    case TK_OPTION_INT:
	objPtr = Tcl_NewWideIntObj(*((int *) internalPtr));
	break;
    case TK_OPTION_DOUBLE:
	objPtr = Tcl_NewDoubleObj(*((double *) internalPtr));
	break;
    case TK_OPTION_STRING:
	objPtr = Tcl_NewStringObj(*((char **) internalPtr), -1);
	break;
    case TK_OPTION_STRING_TABLE:
	objPtr = Tcl_NewStringObj(((char **) optionPtr->specPtr->clientData)[
		*((int *) internalPtr)], -1);
	break;
    case TK_OPTION_COLOR: {
	XColor *colorPtr = *((XColor **) internalPtr);
	case TK_OPTION_INT:
	    objPtr = Tcl_NewWideIntObj(*((int *)internalPtr));
	    break;
	case TK_OPTION_DOUBLE:
	    objPtr = Tcl_NewDoubleObj(*((double *) internalPtr));
	    break;
	case TK_OPTION_STRING:
	    objPtr = Tcl_NewStringObj(*((char **)internalPtr), -1);
	    break;
	case TK_OPTION_STRING_TABLE:
	    objPtr = Tcl_NewStringObj(((char **) optionPtr->specPtr->clientData)[
		    *((int *) internalPtr)], -1);
	    break;
	case TK_OPTION_COLOR: {
	    XColor *colorPtr = *((XColor **)internalPtr);

	if (colorPtr != NULL) {
	    objPtr = Tcl_NewStringObj(Tk_NameOfColor(colorPtr), -1);
	}
	break;
    }
    case TK_OPTION_FONT: {
	Tk_Font tkfont = *((Tk_Font *) internalPtr);
	    if (colorPtr != NULL) {
		objPtr = Tcl_NewStringObj(Tk_NameOfColor(colorPtr), -1);
	    }
	    break;
	}
	case TK_OPTION_FONT: {
	    Tk_Font tkfont = *((Tk_Font *)internalPtr);

	if (tkfont != NULL) {
	    objPtr = Tcl_NewStringObj(Tk_NameOfFont(tkfont), -1);
	}
	break;
    }
    case TK_OPTION_STYLE: {
	Tk_Style style = *((Tk_Style *) internalPtr);
	    if (tkfont != NULL) {
		objPtr = Tcl_NewStringObj(Tk_NameOfFont(tkfont), -1);
	    }
	    break;
	}
	case TK_OPTION_STYLE: {
	    Tk_Style style = *((Tk_Style *)internalPtr);

	if (style != NULL) {
	    objPtr = Tcl_NewStringObj(Tk_NameOfStyle(style), -1);
	}
	break;
    }
    case TK_OPTION_BITMAP: {
	Pixmap pixmap = *((Pixmap *) internalPtr);
	    if (style != NULL) {
		objPtr = Tcl_NewStringObj(Tk_NameOfStyle(style), -1);
	    }
	    break;
	}
	case TK_OPTION_BITMAP: {
	    Pixmap pixmap = *((Pixmap *)internalPtr);

	if (pixmap != None) {
	    objPtr = Tcl_NewStringObj(
	    if (pixmap != None) {
		objPtr = Tcl_NewStringObj(
		    Tk_NameOfBitmap(Tk_Display(tkwin), pixmap), -1);
	}
	break;
    }
    case TK_OPTION_BORDER: {
	Tk_3DBorder border = *((Tk_3DBorder *) internalPtr);
	    }
	    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 (border != NULL) {
		objPtr = Tcl_NewStringObj(Tk_NameOf3DBorder(border), -1);
	    }
	    break;
	}
	case TK_OPTION_RELIEF:
	    objPtr = Tcl_NewStringObj(Tk_NameOfRelief(*((int *)internalPtr)), -1);
	    break;
	case TK_OPTION_CURSOR: {
	    Tk_Cursor cursor = *((Tk_Cursor *)internalPtr);

	if (cursor != NULL) {
	    objPtr = Tcl_NewStringObj(
		    Tk_NameOfCursor(Tk_Display(tkwin), cursor), -1);
	}
	break;
    }
    case TK_OPTION_JUSTIFY:
	objPtr = Tcl_NewStringObj(Tk_NameOfJustify(
		*((Tk_Justify *) internalPtr)), -1);
	break;
    case TK_OPTION_ANCHOR:
	objPtr = Tcl_NewStringObj(Tk_NameOfAnchor(
		*((Tk_Anchor *) internalPtr)), -1);
	break;
    case TK_OPTION_PIXELS:
	objPtr = Tcl_NewWideIntObj(*((int *) internalPtr));
	break;
    case TK_OPTION_WINDOW: {
	Tk_Window tkwin = *((Tk_Window *) internalPtr);
	    if (cursor != NULL) {
		objPtr = Tcl_NewStringObj(
		Tk_NameOfCursor(Tk_Display(tkwin), cursor), -1);
	    }
	    break;
	}
	case TK_OPTION_JUSTIFY:
	    objPtr = Tcl_NewStringObj(Tk_NameOfJustify(
		    *((Tk_Justify *)internalPtr)), -1);
	    break;
	case TK_OPTION_ANCHOR:
	    objPtr = Tcl_NewStringObj(Tk_NameOfAnchor(
		    *((Tk_Anchor *)internalPtr)), -1);
	    break;
	case TK_OPTION_PIXELS:
	    objPtr = Tcl_NewWideIntObj(*((int *)internalPtr));
	    break;
	case TK_OPTION_WINDOW: {
	    tkwin = *((Tk_Window *) internalPtr);

	if (tkwin != NULL) {
	    objPtr = Tcl_NewStringObj(Tk_PathName(tkwin), -1);
	}
	break;
    }
    case TK_OPTION_CUSTOM: {
	const Tk_ObjCustomOption *custom = optionPtr->extra.custom;
	    if (tkwin != NULL) {
		objPtr = Tcl_NewStringObj(Tk_PathName(tkwin), -1);
	    }
	    break;
	}
	case TK_OPTION_CUSTOM: {
	    const Tk_ObjCustomOption *custom = optionPtr->extra.custom;

	objPtr = custom->getProc(custom->clientData, tkwin, (char *)recordPtr,
		optionPtr->specPtr->internalOffset);
	break;
    }
    default:
	Tcl_Panic("bad option type in GetObjectForOption");
	    objPtr = custom->getProc(custom->clientData, tkwin, (char *)recordPtr,
		    optionPtr->specPtr->internalOffset);
	    break;
        }
        default:
	    Tcl_Panic("bad option type in GetObjectForOption");
	}
    }
    if (objPtr == NULL) {
	objPtr = Tcl_NewObj();
    }
    return objPtr;
}

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
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







-
+











-







 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkDebugConfig(
    Tcl_Interp *dummy,		/* Interpreter in which the table is
    TCL_UNUSED(Tcl_Interp *),		/* Interpreter in which the table is
				 * defined. */
    Tk_OptionTable table)	/* Table about which information is to be
				 * returned. May not necessarily exist in the
				 * interpreter anymore. */
{
    OptionTable *tablePtr = (OptionTable *) table;
    Tcl_HashEntry *hashEntryPtr;
    Tcl_HashSearch search;
    Tcl_Obj *objPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)dummy;

    objPtr = Tcl_NewObj();
    if (!tablePtr || !tsdPtr->initialized) {
	return objPtr;
    }

    /*

Changes to generic/tkConsole.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







-
+







/*
 * tkConsole.c --
 *
 *	This file implements a Tcl console for systems that may not otherwise
 *	have access to a console. It uses the Text widget and provides special
 *	access via a console command.
 *
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
 * Copyright © 1995-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77







-
+








/*
 * This structure describes the channel type structure for file based IO:
 */

static const Tcl_ChannelType consoleChannelType = {
    "console",			/* Type name. */
    TCL_CHANNEL_VERSION_5,	/* v4 channel */
    TCL_CHANNEL_VERSION_5,	/* v5 channel */
    (Tcl_DriverCloseProc *)ConsoleClose,		/* Close proc. */
    ConsoleInput,		/* Input proc. */
    ConsoleOutput,		/* Output proc. */
    NULL,			/* Seek proc. */
    NULL,			/* Set option proc. */
    NULL,			/* Get option proc. */
    ConsoleWatch,		/* Watch for events on console. */
557
558
559
560
561
562
563
564
565
566



567
568

569
570
571
572
573
574
575
576
577
578
579
580
581
557
558
559
560
561
562
563



564
565
566
567

568
569





570
571
572
573
574
575
576







-
-
-
+
+
+

-
+

-
-
-
-
-







 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
ConsoleInput(
    void *dummy,		/* Unused. */
    char *buf,			/* Where to store data read. */
    int bufSize,		/* How much space is available in the
    TCL_UNUSED(void *),
    TCL_UNUSED(char *),			/* Where to store data read. */
    TCL_UNUSED(int),		/* How much space is available in the
				 * buffer? */
    int *errorCode)		/* Where to store error code. */
    TCL_UNUSED(int *))		/* Where to store error code. */
{
    (void)dummy;
    (void)buf;
    (void)bufSize;
    (void)errorCode;

    return 0;			/* Always return EOF. */
}

/*
 *----------------------------------------------------------------------
 *
 * ConsoleClose/Console2Close --
590
591
592
593
594
595
596
597

598
599
600
601
602
603
604
605
606
607
608
585
586
587
588
589
590
591

592
593
594
595

596
597
598
599
600
601
602







-
+



-







 *
 *----------------------------------------------------------------------
 */

static int
ConsoleClose(
    ClientData instanceData,
    Tcl_Interp *dummy)		/* Unused. */
    TCL_UNUSED(Tcl_Interp *))
{
    ChannelData *data = (ChannelData *)instanceData;
    ConsoleInfo *info = data->info;
    (void)dummy;

    if (info) {
	if (info->refCount-- <= 1) {
	    /*
	     * Assuming the Tcl_Interp * fields must already be NULL.
	     */

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







-
-
+
+



-
-







 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
ConsoleWatch(
    ClientData dummy,	/* Device ID for the channel. */
    int mask)			/* OR-ed combination of TCL_READABLE,
    TCL_UNUSED(void *),	/* Device ID for the channel. */
    TCL_UNUSED(int))			/* OR-ed combination of TCL_READABLE,
				 * TCL_WRITABLE and TCL_EXCEPTION, for the
				 * events we are interested in. */
{
    (void)dummy;
    (void)mask;
}

/*
 *----------------------------------------------------------------------
 *
 * ConsoleHandle --
 *
669
670
671
672
673
674
675
676
677


678
679
680

681
682
683
684
685
686
687
688
689
690
691
692
661
662
663
664
665
666
667


668
669
670
671

672
673




674
675
676
677
678
679
680







-
-
+
+


-
+

-
-
-
-







 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
ConsoleHandle(
    ClientData dummy,	/* Device ID for the channel. */
    int direction,		/* TCL_READABLE or TCL_WRITABLE to indicate
    TCL_UNUSED(void *),	/* Device ID for the channel. */
    TCL_UNUSED(int),		/* TCL_READABLE or TCL_WRITABLE to indicate
				 * which direction of the channel is being
				 * requested. */
    ClientData *handlePtr)	/* Where to store handle */
    TCL_UNUSED(void **))	/* Where to store handle */
{
    (void)dummy;
    (void)direction;
    (void)handlePtr;

    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * ConsoleObjCmd --
820
821
822
823
824
825
826
827

828
829
830
831
832
833
834
808
809
810
811
812
813
814

815
816
817
818
819
820
821
822







-
+







    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "script");
	return TCL_ERROR;
    }

    if ((otherInterp == NULL) || Tcl_InterpDeleted(otherInterp)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"no active master interp", -1));
		"no active parent interp", -1));
	Tcl_SetErrorCode(interp, "TK", "CONSOLE", "NO_INTERP", NULL);
	return TCL_ERROR;
    }

    Tcl_Preserve(otherInterp);
    switch ((enum option) index) {
    case OTHER_EVAL:
943
944
945
946
947
948
949
950

951
952
953
954
955
956
957
931
932
933
934
935
936
937

938
939
940
941
942
943
944
945







-
+







}

/*
 *----------------------------------------------------------------------
 *
 * ConsoleEventProc --
 *
 *	This event function is registered on the main window of the slave
 *	This event function is registered on the main window of the child
 *	interpreter. If the user or a running script causes the main window to
 *	be destroyed, then we need to inform the console interpreter by
 *	invoking "::tk::ConsoleExit".
 *
 * Results:
 *	None.
 *

Changes to generic/tkCursor.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







-
-
+
+







/*
 * tkCursor.c --
 *
 *	This file maintains a database of read-only cursors for the Tk
 *	toolkit. This allows cursors to be shared between widgets and also
 *	avoids round-trips to the X server.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

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 © 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
1
2
3
4
5

6
7
8
9
10
11
12
13





-
+







/*
 * 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
351
352
353
354
355
356
357
358

359
360
361
362
363
364
365
351
352
353
354
355
356
357

358
359
360
361
362
363
364
365







-
+







				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_GetImageMasterData(Tcl_Interp *interp,
EXTERN ClientData	Tk_GetImageModelData(Tcl_Interp *interp,
				const char *name,
				const Tk_ImageType **typePtrPtr);
/* 99 */
EXTERN Tk_ItemType *	Tk_GetItemTypes(void);
/* 100 */
EXTERN int		Tk_GetJoinStyle(Tcl_Interp *interp, const char *str,
				int *joinPtr);
407
408
409
410
411
412
413
414

415
416
417
418
419
420
421
422
423
424
425
426


427
428
429
430
431
432
433
407
408
409
410
411
412
413

414
415
416
417
418
419
420
421
422
423
424


425
426
427
428
429
430
431
432
433







-
+










-
-
+
+







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_ImageMaster master, int x, int y,
EXTERN void		Tk_ImageChanged(Tk_ImageModel model, int x, int y,
				int width, int height, int imageWidth,
				int imageHeight);
/* 118 */
EXTERN int		Tk_Init(Tcl_Interp *interp);
/* 119 */
EXTERN Atom		Tk_InternAtom(Tk_Window tkwin, const char *name);
/* 120 */
EXTERN int		Tk_IntersectTextLayout(Tk_TextLayout layout, int x,
				int y, int width, int height);
/* 121 */
EXTERN void		Tk_MaintainGeometry(Tk_Window slave,
				Tk_Window master, int x, int y, int width,
EXTERN void		Tk_MaintainGeometry(Tk_Window window,
				Tk_Window container, int x, int y, int width,
				int height);
/* 122 */
EXTERN Tk_Window	Tk_MainWindow(Tcl_Interp *interp);
/* 123 */
EXTERN void		Tk_MakeWindowExist(Tk_Window tkwin);
/* 124 */
EXTERN void		Tk_ManageGeometry(Tk_Window tkwin,
457
458
459
460
461
462
463
464

465
466
467
468
469
470
471
457
458
459
460
461
462
463

464
465
466
467
468
469
470
471







-
+







/* 134 */
EXTERN const char *	Tk_NameOfColor(XColor *colorPtr);
/* 135 */
EXTERN const char *	Tk_NameOfCursor(Display *display, Tk_Cursor cursor);
/* 136 */
EXTERN const char *	Tk_NameOfFont(Tk_Font font);
/* 137 */
EXTERN const char *	Tk_NameOfImage(Tk_ImageMaster imageMaster);
EXTERN const char *	Tk_NameOfImage(Tk_ImageModel model);
/* 138 */
EXTERN const char *	Tk_NameOfJoinStyle(int join);
/* 139 */
EXTERN const char *	Tk_NameOfJustify(Tk_Justify justify);
/* 140 */
EXTERN const char *	Tk_NameOfRelief(int relief);
/* 141 */
590
591
592
593
594
595
596
597
598


599
600
601
602
603
604
605
590
591
592
593
594
595
596


597
598
599
600
601
602
603
604
605







-
-
+
+







EXTERN void		Tk_UnderlineTextLayout(Display *display,
				Drawable drawable, GC gc,
				Tk_TextLayout layout, int x, int y,
				int underline);
/* 180 */
EXTERN void		Tk_Ungrab(Tk_Window tkwin);
/* 181 */
EXTERN void		Tk_UnmaintainGeometry(Tk_Window slave,
				Tk_Window master);
EXTERN void		Tk_UnmaintainGeometry(Tk_Window window,
				Tk_Window container);
/* 182 */
EXTERN void		Tk_UnmapWindow(Tk_Window tkwin);
/* 183 */
EXTERN void		Tk_UnsetGrid(Tk_Window tkwin);
/* 184 */
EXTERN void		Tk_UpdatePointer(Tk_Window tkwin, int x, int y,
				int state);
875
876
877
878
879
880
881















882
883
884
885
886
887
888
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







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







EXTERN Tcl_Interp *	Tk_Interp(Tk_Window tkwin);
/* 272 */
EXTERN void		Tk_CreateOldImageType(const Tk_ImageType *typePtr);
/* 273 */
EXTERN void		Tk_CreateOldPhotoImageFormat(
				const Tk_PhotoImageFormat *formatPtr);
/* 274 */
EXTERN int		Tk_AlwaysShowSelection(Tk_Window tkwin);
/* 275 */
EXTERN unsigned		Tk_GetButtonMask(unsigned button);
/* 276 */
EXTERN int		Tk_GetDoublePixelsFromObj(Tcl_Interp *interp,
				Tk_Window tkwin, Tcl_Obj *objPtr,
				double *doublePtr);
/* 277 */
EXTERN Tcl_Obj *	Tk_NewWindowObj(Tk_Window tkwin);
/* 278 */
EXTERN void		Tk_SendVirtualEvent(Tk_Window tkwin,
				const char *eventName, Tcl_Obj *detail);
/* 279 */
EXTERN Tcl_Obj *	Tk_FontGetDescription(Tk_Font tkfont);
/* 280 */
EXTERN void		Tk_CreatePhotoImageFormatVersion3(
				const Tk_PhotoImageFormatVersion3 *formatPtr);

typedef struct {
    const struct TkPlatStubs *tkPlatStubs;
    const struct TkIntStubs *tkIntStubs;
    const struct TkIntPlatStubs *tkIntPlatStubs;
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
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







-
+


















-
+



-
+















-
+







    Tk_Cursor (*tk_GetCursor) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid str); /* 91 */
    Tk_Cursor (*tk_GetCursorFromData) (Tcl_Interp *interp, Tk_Window tkwin, const char *source, const char *mask, int width, int height, int xHot, int yHot, Tk_Uid fg, Tk_Uid bg); /* 92 */
    Tk_Font (*tk_GetFont) (Tcl_Interp *interp, Tk_Window tkwin, const char *str); /* 93 */
    Tk_Font (*tk_GetFontFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 94 */
    void (*tk_GetFontMetrics) (Tk_Font font, Tk_FontMetrics *fmPtr); /* 95 */
    GC (*tk_GetGC) (Tk_Window tkwin, unsigned long valueMask, XGCValues *valuePtr); /* 96 */
    Tk_Image (*tk_GetImage) (Tcl_Interp *interp, Tk_Window tkwin, const char *name, Tk_ImageChangedProc *changeProc, ClientData clientData); /* 97 */
    ClientData (*tk_GetImageMasterData) (Tcl_Interp *interp, const char *name, const Tk_ImageType **typePtrPtr); /* 98 */
    ClientData (*tk_GetImageModelData) (Tcl_Interp *interp, const char *name, const Tk_ImageType **typePtrPtr); /* 98 */
    Tk_ItemType * (*tk_GetItemTypes) (void); /* 99 */
    int (*tk_GetJoinStyle) (Tcl_Interp *interp, const char *str, int *joinPtr); /* 100 */
    int (*tk_GetJustify) (Tcl_Interp *interp, const char *str, Tk_Justify *justifyPtr); /* 101 */
    int (*tk_GetNumMainWindows) (void); /* 102 */
    Tk_Uid (*tk_GetOption) (Tk_Window tkwin, const char *name, const char *className); /* 103 */
    int (*tk_GetPixels) (Tcl_Interp *interp, Tk_Window tkwin, const char *str, int *intPtr); /* 104 */
    Pixmap (*tk_GetPixmap) (Display *display, Drawable d, int width, int height, int depth); /* 105 */
    int (*tk_GetRelief) (Tcl_Interp *interp, const char *name, int *reliefPtr); /* 106 */
    void (*tk_GetRootCoords) (Tk_Window tkwin, int *xPtr, int *yPtr); /* 107 */
    int (*tk_GetScrollInfo) (Tcl_Interp *interp, int argc, const char **argv, double *dblPtr, int *intPtr); /* 108 */
    int (*tk_GetScreenMM) (Tcl_Interp *interp, Tk_Window tkwin, const char *str, double *doublePtr); /* 109 */
    int (*tk_GetSelection) (Tcl_Interp *interp, Tk_Window tkwin, Atom selection, Atom target, Tk_GetSelProc *proc, ClientData clientData); /* 110 */
    Tk_Uid (*tk_GetUid) (const char *str); /* 111 */
    Visual * (*tk_GetVisual) (Tcl_Interp *interp, Tk_Window tkwin, const char *str, int *depthPtr, Colormap *colormapPtr); /* 112 */
    void (*tk_GetVRootGeometry) (Tk_Window tkwin, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); /* 113 */
    int (*tk_Grab) (Tcl_Interp *interp, Tk_Window tkwin, int grabGlobal); /* 114 */
    void (*tk_HandleEvent) (XEvent *eventPtr); /* 115 */
    Tk_Window (*tk_IdToWindow) (Display *display, Window window); /* 116 */
    void (*tk_ImageChanged) (Tk_ImageMaster master, int x, int y, int width, int height, int imageWidth, int imageHeight); /* 117 */
    void (*tk_ImageChanged) (Tk_ImageModel model, int x, int y, int width, int height, int imageWidth, int imageHeight); /* 117 */
    int (*tk_Init) (Tcl_Interp *interp); /* 118 */
    Atom (*tk_InternAtom) (Tk_Window tkwin, const char *name); /* 119 */
    int (*tk_IntersectTextLayout) (Tk_TextLayout layout, int x, int y, int width, int height); /* 120 */
    void (*tk_MaintainGeometry) (Tk_Window slave, Tk_Window master, int x, int y, int width, int height); /* 121 */
    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_ImageMaster imageMaster); /* 137 */
    const char * (*tk_NameOfImage) (Tk_ImageModel model); /* 137 */
    const char * (*tk_NameOfJoinStyle) (int join); /* 138 */
    const char * (*tk_NameOfJustify) (Tk_Justify justify); /* 139 */
    const char * (*tk_NameOfRelief) (int relief); /* 140 */
    Tk_Window (*tk_NameToWindow) (Tcl_Interp *interp, const char *pathName, Tk_Window tkwin); /* 141 */
    void (*tk_OwnSelection) (Tk_Window tkwin, Atom selection, Tk_LostSelProc *proc, ClientData clientData); /* 142 */
    int (*tk_ParseArgv) (Tcl_Interp *interp, Tk_Window tkwin, int *argcPtr, const char **argv, const Tk_ArgvInfo *argTable, int flags); /* 143 */
    TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoPutBlock_NoComposite) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height); /* 144 */
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







-
+







    int (*tk_StrictMotif) (Tk_Window tkwin); /* 174 */
    void (*tk_TextLayoutToPostscript) (Tcl_Interp *interp, Tk_TextLayout layout); /* 175 */
    int (*tk_TextWidth) (Tk_Font font, const char *str, int numBytes); /* 176 */
    void (*tk_UndefineCursor) (Tk_Window window); /* 177 */
    void (*tk_UnderlineChars) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *source, int x, int y, int firstByte, int lastByte); /* 178 */
    void (*tk_UnderlineTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, int underline); /* 179 */
    void (*tk_Ungrab) (Tk_Window tkwin); /* 180 */
    void (*tk_UnmaintainGeometry) (Tk_Window slave, Tk_Window master); /* 181 */
    void (*tk_UnmaintainGeometry) (Tk_Window window, Tk_Window container); /* 181 */
    void (*tk_UnmapWindow) (Tk_Window tkwin); /* 182 */
    void (*tk_UnsetGrid) (Tk_Window tkwin); /* 183 */
    void (*tk_UpdatePointer) (Tk_Window tkwin, int x, int y, int state); /* 184 */
    Pixmap (*tk_AllocBitmapFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); /* 185 */
    Tk_3DBorder (*tk_Alloc3DBorderFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); /* 186 */
    XColor * (*tk_AllocColorFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); /* 187 */
    Tk_Cursor (*tk_AllocCursorFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); /* 188 */
1163
1164
1165
1166
1167
1168
1169






1170
1171

1172
1173
1174
1175
1176
1177
1178
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191

1192
1193
1194
1195
1196
1197
1198
1199







+
+
+
+
+
+

-
+







    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 (*tk_CreatePhotoImageFormatVersion3) (
	    const Tk_PhotoImageFormatVersion3 *formatPtr);  /* 274 */
	    const Tk_PhotoImageFormatVersion3 *formatPtr);  /* 280 */
} TkStubs;

extern const TkStubs *tkStubsPtr;

#ifdef __cplusplus
}
#endif
1375
1376
1377
1378
1379
1380
1381
1382
1383


1384
1385
1386
1387
1388
1389
1390
1396
1397
1398
1399
1400
1401
1402


1403
1404
1405
1406
1407
1408
1409
1410
1411







-
-
+
+







	(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_GetImageMasterData \
	(tkStubsPtr->tk_GetImageMasterData) /* 98 */
#define Tk_GetImageModelData \
	(tkStubsPtr->tk_GetImageModelData) /* 98 */
#define Tk_GetItemTypes \
	(tkStubsPtr->tk_GetItemTypes) /* 99 */
#define Tk_GetJoinStyle \
	(tkStubsPtr->tk_GetJoinStyle) /* 100 */
#define Tk_GetJustify \
	(tkStubsPtr->tk_GetJustify) /* 101 */
#define Tk_GetNumMainWindows \
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
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







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

-
+

















-
+





















+
+

	(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 */
#define Tk_CreatePhotoImageFormatVersion3 \
	(tkStubsPtr->tk_CreatePhotoImageFormatVersion3) /* 274 */
	(tkStubsPtr->tk_CreatePhotoImageFormatVersion3) /* 280 */

#endif /* defined(USE_TK_STUBS) */

/* !END!: Do not edit above this line. */

/* Functions that don't belong in the stub table */
#undef Tk_MainEx
#undef Tk_Init
#undef Tk_SafeInit
#undef Tk_CreateConsoleWindow

#undef Tk_FreeXId
#define Tk_FreeXId(display,xid)
#undef Tk_GetStyleFromObj
#undef Tk_FreeStyleFromObj
#define Tk_GetStyleFromObj(obj) Tk_AllocStyleFromObj(NULL, obj)
#define Tk_FreeStyleFromObj(obj) /* no-op */

#define Tk_GetImageMasterData Tk_GetImageModelData

#if defined(_WIN32) && defined(UNICODE)
#   define Tk_MainEx Tk_MainExW
    EXTERN void Tk_MainExW(int argc, wchar_t **argv,
	    Tcl_AppInitProc *appInitProc, Tcl_Interp *interp);
#endif


#if defined(TK_NO_DEPRECATED) || TCL_MAJOR_VERSION > 8
#undef Tk_PhotoPutBlock_NoComposite
#undef Tk_PhotoPutZoomedBlock_NoComposite
#undef Tk_PhotoExpand_Panic
#undef Tk_PhotoPutBlock_Panic
#undef Tk_PhotoPutZoomedBlock_Panic
#undef Tk_PhotoSetSize_Panic
#undef Tk_CreateOldPhotoImageFormat
#endif /* TK_NO_DEPRECATED */

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#undef TkUnusedStubEntry

#endif /* _TKDECLS */

Changes to generic/tkEntry.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








-
-
-
-
+
+
+
+







/*
 * tkEntry.c --
 *
 *	This module implements entry and spinbox widgets for the Tk toolkit.
 *	An entry displays a string and allows the string to be edited. A
 *	spinbox expands on the entry by adding up/down buttons that control
 *	the value of the entry widget.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 2000 Ajuba Solutions.
 * Copyright (c) 2002 ActiveState Corporation.
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 2000 Ajuba Solutions.
 * Copyright © 2002 ActiveState Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkEntry.h"
570
571
572
573
574
575
576
577

578
579
580
581
582
583
584
570
571
572
573
574
575
576

577
578
579
580
581
582
583
584







-
+







    if ((Tk_InitOptions(interp, entryPtr, optionTable, tkwin)
	    != TCL_OK) ||
	    (ConfigureEntry(interp, entryPtr, objc-2, objv+2) != TCL_OK)) {
	Tk_DestroyWindow(entryPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, TkNewWindowObj(entryPtr->tkwin));
    Tcl_SetObjResult(interp, Tk_NewWindowObj(entryPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * EntryWidgetObjCmd --
733
734
735
736
737
738
739
740

741
742
743
744
745
746
747
733
734
735
736
737
738
739

740
741
742
743
744
745
746
747







-
+







	    Tcl_WrongNumArgs(interp, 2, objv, "string");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&index) != TCL_OK) {
	    goto error;
	}
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index));
	Tcl_SetObjResult(interp, TkNewIndexObj(index));
	break;
    }

    case COMMAND_INSERT: {
	TkSizeT index;
	int code;

1680
1681
1682
1683
1684
1685
1686
1687

1688
1689
1690
1691
1692
1693
1694
1680
1681
1682
1683
1684
1685
1686

1687
1688
1689
1690
1691
1692
1693
1694







-
+







    xBound = Tk_Width(tkwin) - entryPtr->inset - entryPtr->xWidth;
    baseY = (Tk_Height(tkwin) + fm.ascent - fm.descent) / 2;

    /*
     * Hide the selection whenever we don't have the focus, unless we
     * always want to show selection.
     */
    if (TkpAlwaysShowSelection(entryPtr->tkwin)) {
    if (Tk_AlwaysShowSelection(entryPtr->tkwin)) {
	showSelection = 1;
    } else {
	showSelection = (entryPtr->flags & GOT_FOCUS);
    }

    /*
     * Draw the background in three layers. From bottom to top the layers are:
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
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







+
+
-
-
+
+
-
-
+

-
-
-
-
-
-
+


-
+
+

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

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







		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 text in two pieces: first the unselected portion, then the
        /*
         * Draw the placeholder text.
     * selected portion on top of it.
     */
         */

    if ((entryPtr->numChars != 0) || (entryPtr->placeholderChars == 0)) {
        Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->textGC,
	    entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,
	    entryPtr->leftIndex, entryPtr->numChars);
    } else {
	Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->placeholderGC,
        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)) {
	int selFirst;
        if (showSelection && (entryPtr->state != STATE_DISABLED)
	        && (entryPtr->selTextGC != entryPtr->textGC)
	        && (entryPtr->selectFirst + 1 < entryPtr->selectLast + 1)) {

	    /*
	     * Draw the selected and unselected portions separately.
	     */

	    TkSizeT selFirst;

	if (entryPtr->selectFirst + 1 < entryPtr->leftIndex + 1) {
	    selFirst = entryPtr->leftIndex;
	} else {
	    selFirst = entryPtr->selectFirst;
	}
	Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->selTextGC,
		entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,
		selFirst, entryPtr->selectLast);
	    if (entryPtr->selectFirst + 1 < entryPtr->leftIndex + 1) {
	        selFirst = entryPtr->leftIndex;
	    } else {
	        selFirst = entryPtr->selectFirst;
	    }
	    if (entryPtr->leftIndex < selFirst) {
	        Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->textGC,
		        entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,
		        entryPtr->leftIndex, selFirst);
	    }
	    Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->selTextGC,
		    entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,
		    selFirst, entryPtr->selectLast);
	    if (entryPtr->selectLast < entryPtr->numChars) {
	        Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->textGC,
		        entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,
		        entryPtr->selectLast, entryPtr->numChars);
	    }
        } else {

            /*
             * Draw the entire visible text
             */

	    Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->textGC,
		    entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,
		    entryPtr->leftIndex, entryPtr->numChars);
        }
    }

    if (entryPtr->type == TK_SPINBOX) {
	int startx, height, inset, pad, tHeight, xWidth;
	Spinbox *sbPtr = (Spinbox *) entryPtr;

	/*
2664
2665
2666
2667
2668
2669
2670
2671

2672
2673
2674
2675
2676
2677
2678
2686
2687
2688
2689
2690
2691
2692

2693
2694
2695
2696
2697
2698
2699
2700







-
+







	} else if (idx > entryPtr->numChars) {
	    idx = entryPtr->numChars;
	}
	*indexPtr = idx;
	return TCL_OK;
    }

    string = TkGetStringFromObj(indexObj, &length);
    string = Tcl_GetStringFromObj(indexObj, &length);

    switch (string[0]) {
    case 'a':
	if (strncmp(string, "anchor", length) != 0) {
	    goto badIndex;
	}
	*indexPtr = entryPtr->selectAnchor;
2952
2953
2954
2955
2956
2957
2958
2959

2960
2961
2962
2963
2964
2965
2966
2974
2975
2976
2977
2978
2979
2980

2981
2982
2983
2984
2985
2986
2987
2988







-
+







    /*
     * On Windows and Mac systems, we want to remember the selection for the
     * next time the focus enters the window. On Unix, we need to clear the
     * selection since it is always visible.
     * This is controlled by ::tk::AlwaysShowSelection.
     */

    if (TkpAlwaysShowSelection(entryPtr->tkwin)
    if (Tk_AlwaysShowSelection(entryPtr->tkwin)
	    && (entryPtr->selectFirst != TCL_INDEX_NONE) && entryPtr->exportSelection
	    && (!Tcl_IsSafe(entryPtr->interp))) {
	entryPtr->selectFirst = TCL_INDEX_NONE;
	entryPtr->selectLast = TCL_INDEX_NONE;
	EventuallyRedraw(entryPtr);
    }
}
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
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







+
+
+




-
-
-
+
+
+




+







{
    int code, varValidate = (entryPtr->flags & VALIDATE_VAR);
    char *p;
    Tcl_DString script;

    if (entryPtr->validateCmd == NULL ||
	entryPtr->validate == VALIDATE_NONE) {
        if (entryPtr->flags & VALIDATING) {
            entryPtr->flags |= VALIDATE_ABORT;
        }
	return (varValidate ? TCL_ERROR : TCL_OK);
    }

    /*
     * If we're already validating, then we're hitting a loop condition Return
     * and set validate to 0 to disallow further validations and prevent
     * current validation from finishing
     * If we're already validating, then we're hitting a loop condition. Set
     * validate to none to disallow further validations, arrange for flags
     * to prevent current validation from finishing, and return.
     */

    if (entryPtr->flags & VALIDATING) {
	entryPtr->validate = VALIDATE_NONE;
        entryPtr->flags |= VALIDATE_ABORT;
	return (varValidate ? TCL_ERROR : TCL_OK);
    }

    entryPtr->flags |= VALIDATING;

    /*
     * Now form command string and run through the -validatecommand
3777
3778
3779
3780
3781
3782
3783
3784

3785
3786
3787
3788
3789
3790
3791
3803
3804
3805
3806
3807
3808
3809

3810
3811
3812
3813
3814
3815
3816
3817







-
+







	Tk_DestroyWindow(entryPtr->tkwin);
	return TCL_ERROR;
    }
    if (ConfigureEntry(interp, entryPtr, objc-2, objv+2) != TCL_OK) {
	goto error;
    }

    Tcl_SetObjResult(interp, TkNewWindowObj(entryPtr->tkwin));
    Tcl_SetObjResult(interp, Tk_NewWindowObj(entryPtr->tkwin));
    return TCL_OK;

  error:
    Tk_DestroyWindow(entryPtr->tkwin);
    return TCL_ERROR;
}

3965
3966
3967
3968
3969
3970
3971
3972

3973
3974
3975
3976
3977
3978
3979
3991
3992
3993
3994
3995
3996
3997

3998
3999
4000
4001
4002
4003
4004
4005







-
+







	    Tcl_WrongNumArgs(interp, 2, objv, "string");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&index) != TCL_OK) {
	    goto error;
	}
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj((int)index));
	Tcl_SetObjResult(interp, TkNewIndexObj(index));
	break;
    }

    case SB_CMD_INSERT: {
	TkSizeT index;
	int code;

4403
4404
4405
4406
4407
4408
4409
4410

4411
4412
4413
4414
4415
4416
4417
4429
4430
4431
4432
4433
4434
4435

4436
4437
4438
4439
4440
4441
4442
4443







-
+







		int i, listc;
		TkSizeT elemLen, length = entryPtr->numChars;
		const char *bytes;
		Tcl_Obj **listv;

		Tcl_ListObjGetElements(interp, sbPtr->listObj, &listc, &listv);
		for (i = 0; i < listc; i++) {
		    bytes = TkGetStringFromObj(listv[i], &elemLen);
		    bytes = Tcl_GetStringFromObj(listv[i], &elemLen);
		    if ((length == elemLen) &&
			    (memcmp(bytes, entryPtr->string,
				    length) == 0)) {
			sbPtr->eIndex = i;
			break;
		    }
		}

Changes to generic/tkEntry.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








-
+







/*
 *  tkEntry.h --
 *
 * This module defined the structures for the Entry & SpinBox widgets.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * Copyright (c) 2002 Apple Inc.
 * Copyright © 2002 Apple Inc.
 */

#ifndef _TKENTRY
#define _TKENTRY

#ifndef _TKINT
#include "tkInt.h"

Changes to generic/tkError.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








-
-
+
+







/*
 * tkError.c --
 *
 *	This file provides a high-performance mechanism for selectively
 *	dealing with errors that occur in talking to the X server. This is
 *	useful, for example, when communicating with a window that may not
 *	exist.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1995 Sun Microsystems, Inc.
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

Changes to generic/tkEvent.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






-
-
-
-
+
+
+
+







/*
 * tkEvent.c --
 *
 *	This file provides basic low-level facilities for managing X events in
 *	Tk.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1995 Sun Microsystems, Inc.
 * Copyright (c) 1998-2000 Ajuba Solutions.
 * Copyright (c) 2004 George Peter Staplin
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1995 Sun Microsystems, Inc.
 * Copyright © 1998-2000 Ajuba Solutions.
 * Copyright © 2004 George Peter Staplin
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

509
510
511
512
513
514
515
516

517
518




519
520
521
522
523
524
525
526
527
528
529
530
531



532
533
534
535
536



537
538
539
540
541
542
543
509
510
511
512
513
514
515

516
517

518
519
520
521
522
523
524
525
526
527
528
529
530
531



532
533
534
535
536



537
538
539
540
541
542
543
544
545
546







-
+

-
+
+
+
+










-
-
-
+
+
+


-
-
-
+
+
+







    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetButtonMask --
 * Tk_GetButtonMask --
 *
 *	Return the proper Button${n}Mask for the button.
 *	Return the proper Button${n}Mask for the button. Don't care about
 *	Button4 - Button7, because those are not actually buttons: Those
 *	are used for the horizontal or vertical mouse wheels. Button4Mask
 *	and higher is actually used for Button 8 and higher.
 *
 * Results:
 *	A button mask.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static const unsigned long buttonMasks[] = {
    0, Button1Mask, Button2Mask, Button3Mask, Button4Mask, Button5Mask,
    Button6Mask, Button7Mask, Button8Mask, Button9Mask
static const unsigned buttonMasks[] = {
    0, Button1Mask, Button2Mask, Button3Mask, 0, 0, 0, 0, Button4Mask, \
	    Button5Mask, Button6Mask, Button7Mask, Button8Mask, Button9Mask
};

unsigned long
TkGetButtonMask(
    unsigned int button)
unsigned
Tk_GetButtonMask(
    unsigned button)
{
    return (button > Button9) ? 0 : buttonMasks[button];
}

/*
 *----------------------------------------------------------------------
 *
687
688
689
690
691
692
693
694

695
696
697
698
699
700
701
690
691
692
693
694
695
696

697
698
699
700
701
702
703
704







-
+







    Tk_Window token,		/* Token for window in which to create
				 * handler. */
    unsigned long mask,		/* Events for which proc should be called. */
    Tk_EventProc *proc,		/* Function to call for each selected event */
    ClientData clientData)	/* Arbitrary data to pass to proc. */
{
    TkEventHandler *handlerPtr;
    TkWindow *winPtr = (TkWindow *) token;
    TkWindow *winPtr = (TkWindow *)token;

    /*
     * Skim through the list of existing handlers to (a) compute the overall
     * event mask for the window (so we can pass this new value to the X
     * system) and (b) see if there's already a handler declared with the same
     * callback and clientData (if so, just change the mask). If no existing
     * handler matches, then create a new handler.
1036
1037
1038
1039
1040
1041
1042
1043

1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1039
1040
1041
1042
1043
1044
1045

1046
1047
1048

1049
1050
1051
1052
1053
1054
1055







-
+


-







 *
 *----------------------------------------------------------------------
 */

static int
TkXErrorHandler(
    ClientData clientData,	/* Pointer to flag we set. */
    XErrorEvent *errEventPtr)	/* X error info. */
    TCL_UNUSED(XErrorEvent *))	/* X error info. */
{
    int *error = (int *)clientData;
    (void)errEventPtr;

    *error = 1;
    return 0;
}

/*
 *----------------------------------------------------------------------
1134
1135
1136
1137
1138
1139
1140

















1141
1142
1143
1144
1145
1146
1147
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







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







    TkWindow *winPtr;
    unsigned long mask;
    InProgress ip;
    Tcl_Interp *interp = NULL;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


#if !defined(_WIN32) && !defined(MAC_OSX_TK)
    if ((eventPtr->xbutton.button >= Button4) && (eventPtr->xbutton.button < Button8)) {
	if (eventPtr->type == ButtonRelease) {
	    return;
	} else if (eventPtr->type == ButtonPress) {
	    int but = eventPtr->xbutton.button;
	    eventPtr->type = MouseWheelEvent;
	    eventPtr->xany.send_event = -1;
	    eventPtr->xkey.keycode = (but & 1) ? -120 : 120;
	    if (but > Button5) {
		eventPtr->xkey.state ^= ShiftMask;
	    }
	}
    }
#endif

    /*
     * If the generic handler processed this event we are done and can return.
     */

    if (InvokeGenericHandlers(tsdPtr, eventPtr)) {
	goto releaseEventResources;
    }
1999
2000
2001
2002
2003
2004
2005
2006

2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2018
2019
2020
2021
2022
2023
2024

2025
2026
2027

2028
2029
2030
2031
2032
2033
2034







-
+


-







 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkFinalize(
    ClientData dummy)	/* Arbitrary value to pass to proc. */
    TCL_UNUSED(void *))	/* Arbitrary value to pass to proc. */
{
    ExitHandler *exitPtr;
    (void)dummy;

#if defined(_WIN32) && !defined(STATIC_BUILD)
    if (!tclStubsPtr) {
	return;
    }
#endif

2052
2053
2054
2055
2056
2057
2058
2059

2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2070
2071
2072
2073
2074
2075
2076

2077
2078
2079
2080
2081

2082
2083
2084
2085
2086
2087
2088







-
+




-







 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkFinalizeThread(
    ClientData dummy)	/* Arbitrary value to pass to proc. */
    TCL_UNUSED(void *))	/* Arbitrary value to pass to proc. */
{
    ExitHandler *exitPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)dummy;

    Tcl_DeleteThreadExitHandler(TkFinalizeThread, NULL);

    if (tsdPtr != NULL) {
	tsdPtr->inExit = 1;

	for (exitPtr = tsdPtr->firstExitPtr; exitPtr != NULL;

Changes to generic/tkFileFilter.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






-
+







/*
 * tkFileFilter.c --
 *
 *	Process the -filetypes option for the file dialogs on Windows and the
 *	Mac.
 *
 * Copyright (c) 1996 Sun Microsystems, Inc.
 * Copyright © 1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkFileFilter.h"
259
260
261
262
263
264
265
266

267
268
269
270
271
272
273
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);
	    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).
319
320
321
322
323
324
325
326

327
328
329
330
331
332
333
319
320
321
322
323
324
325

326
327
328
329
330
331
332
333







-
+







    }
    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);
	    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 "*"
		 */

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







-
+







	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);
	    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
	     */

Changes to generic/tkFileFilter.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






-
+







/*
 * tkFileFilter.h --
 *
 *	Declarations for the file filter processing routines needed by the
 *	file selection dialogs.
 *
 * Copyright (c) 1996 Sun Microsystems, Inc.
 * Copyright © 1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TK_FILE_FILTER
#define _TK_FILE_FILTER

Changes to generic/tkFocus.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





-
-
+
+







/*
 * tkFocus.c --
 *
 *	This file contains functions that manage the input focus for Tk.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

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, TkNewWindowObj(focusWin));
	    Tcl_SetObjResult(interp, Tk_NewWindowObj(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, TkNewWindowObj((Tk_Window) newPtr));
	    Tcl_SetObjResult(interp, Tk_NewWindowObj((Tk_Window) newPtr));
	}
	break;
    case 1:			/* -force */
	windowName = Tcl_GetString(objv[2]);

	/*
	 * The empty string case exists for backwards compatibility.
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, TkNewWindowObj((Tk_Window)
		    Tcl_SetObjResult(interp, Tk_NewWindowObj((Tk_Window)
			    tlFocusPtr->focusWinPtr));
		    return TCL_OK;
		}
	    }
	    Tcl_SetObjResult(interp, TkNewWindowObj((Tk_Window) topLevelPtr));
	    Tcl_SetObjResult(interp, Tk_NewWindowObj((Tk_Window) topLevelPtr));
	    return TCL_OK;
	}
	break;
    default:
	Tcl_Panic("bad const entries to focusOptions in focus command");
    }
    return TCL_OK;

Changes to generic/tkFont.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






-
-
+
+







+
+
+







/*
 * tkFont.c --
 *
 *	This file maintains a database of fonts for the Tk toolkit. It also
 *	provides several utility functions for measuring and displaying text.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1998 Sun Microsystems, Inc.
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1998 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkFont.h"
#if defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"    /* Defines TK_DRAW_IN_CONTEXT */
#endif

/*
 * The following structure is used to keep track of all the fonts that exist
 * in the current application. It must be stored in the TkMainInfo for the
 * application.
 */

89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
92
93
94
95
96
97
98

99
100
101
102
103
104
105
106







-
+







typedef struct TextLayout {
    Tk_Font tkfont;		/* The font used when laying out the text. */
    const char *string;		/* The string that was layed out. */
    int width;			/* The maximum width of all lines in the text
				 * layout. */
    int numChunks;		/* Number of chunks actually used in following
				 * array. */
    LayoutChunk chunks[1];	/* Array of chunks. The actual size will be
    LayoutChunk chunks[TKFLEXARRAY];/* Array of chunks. The actual size will be
				 * maxChunks. THIS FIELD MUST BE THE LAST IN
				 * THE STRUCTURE. */
} TextLayout;

/*
 * The following structures are used as two-way maps between the values for
 * the fields in the TkFontAttributes structure and the strings used in Tcl,
549
550
551
552
553
554
555
556

557
558
559
560
561
562
563
552
553
554
555
556
557
558

559
560
561
562
563
564
565
566







-
+








	/*
	 * 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.
	 */

726
727
728
729
730
731
732
733

734
735
736
737
738
739
740
741

742
743
744
745
746
747
748
749
750
751
752
753

754
755
756
757
758
759
760
729
730
731
732
733
734
735

736
737
738
739
740
741
742
743

744
745
746
747
748
749
750
751
752
753
754
755

756
757
758
759
760
761
762
763







-
+







-
+











-
+







		    "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);
	string = Tcl_GetStringFromObj(objv[3 + skip], &length);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
		Tk_TextWidth(tkfont, string, length)));
	Tk_FreeFont(tkfont);
	break;
    }
    case FONT_METRICS: {
	Tk_Font tkfont;
	int skip, index, i;
	int skip, i;
	const TkFontMetrics *fmPtr;
	static const char *const switches[] = {
	    "-ascent", "-descent", "-linespace", "-fixed", NULL
	};

	skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin);
	if (skip < 0) {
	    return TCL_ERROR;
	}
	if ((objc < 3) || ((objc - skip) > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "font ?-displayof window? ?option?");
		    "font ?-displayof window? ?-option?");
	    return TCL_ERROR;
	}
	tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]);
	if (tkfont == NULL) {
	    return TCL_ERROR;
	}
	objc -= skip;
877
878
879
880
881
882
883
884

885
886
887
888
889
890
891
880
881
882
883
884
885
886

887
888
889
890
891
892
893
894







-
+







    /*
     * On macOS it is catastrophic to recompute all widgets while the
     * [NSView drawRect] method is drawing. The best that we can do in
     * that situation is to abort the recomputation and hope for the best.
     * This is ignored on other platforms.
     */

    if (!TkpWillDrawWidget(NULL)) {
    if (TkpWillDrawWidget(NULL)) {
	return;
    }

    fiPtr->updatePending = 0;
    RecomputeWidgets(fiPtr->mainPtr->winPtr);
}

1355
1356
1357
1358
1359
1360
1361
1362

1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1358
1359
1360
1361
1362
1363
1364

1365
1366
1367
1368

1369
1370
1371
1372
1373
1374
1375







-
+



-







 *	TkFont pointer is NULL.
 *
 *----------------------------------------------------------------------
 */

static int
SetFontFromAny(
    Tcl_Interp *dummy,		/* Used for error reporting if not NULL. */
    TCL_UNUSED(Tcl_Interp *),	/* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr)		/* The object to convert. */
{
    const Tcl_ObjType *typePtr;
    (void)dummy;

    /*
     * Free the old internalRep before setting the new one.
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
1962
1963
1964
1965
1966
1967
1968
1969

1970
1971
1972
1973
1974
1975
1976
1964
1965
1966
1967
1968
1969
1970

1971
1972
1973
1974
1975
1976
1977
1978







-
+







				 * expanded. TK_IGNORE_NEWLINES means that
				 * newline characters should not cause a line
				 * break. */
    int *widthPtr,		/* Filled with width of string. */
    int *heightPtr)		/* Filled with height of string. */
{
    TkFont *fontPtr = (TkFont *) tkfont;
    const char *start, *end, *special;
    const char *start, *endp, *special;
    int n, y, bytesThisChunk, maxChunks, curLine, layoutHeight;
    int baseline, height, curX, newX, maxWidth, *lineLengths;
    TextLayout *layoutPtr;
    LayoutChunk *chunkPtr;
    const TkFontMetrics *fmPtr;
    Tcl_DString lineBuffer;

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
1997
1998
1999
2000
2001
2002
2003


2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018

2019
2020
2021
2022
2023

2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034

2035
2036
2037
2038
2039
2040
2041
2042







-
-
+
+













-
+




-
+










-
+







    }
    if (wrapLength == 0) {
	wrapLength = -1;
    }

    maxChunks = 1;

    layoutPtr = (TextLayout *)ckalloc(sizeof(TextLayout)
	    + (maxChunks-1) * sizeof(LayoutChunk));
    layoutPtr = (TextLayout *)ckalloc(offsetof(TextLayout, chunks)
	    + maxChunks * sizeof(LayoutChunk));
    layoutPtr->tkfont = tkfont;
    layoutPtr->string = string;
    layoutPtr->numChunks = 0;

    baseline = fmPtr->ascent;
    maxWidth = 0;

    /*
     * Divide the string up into simple strings and measure each string.
     */

    curX = 0;

    end = Tcl_UtfAtIndex(string, numChars);
    endp = Tcl_UtfAtIndex(string, numChars);
    special = string;

    flags &= TK_IGNORE_TABS | TK_IGNORE_NEWLINES;
    flags |= TK_WHOLE_WORDS | TK_AT_LEAST_ONE;
    for (start = string; start < end; ) {
    for (start = string; start < endp; ) {
	if (start >= special) {
	    /*
	     * Find the next special character in the string.
	     *
	     * INTL: Note that it is safe to increment by byte, because we are
	     * looking for 7-bit characters that will appear unchanged in
	     * UTF-8. At some point we may need to support the full Unicode
	     * whitespace set.
	     */

	    for (special = start; special < end; special++) {
	    for (special = start; special < endp; special++) {
		if (!(flags & TK_IGNORE_NEWLINES)) {
		    if ((*special == '\n') || (*special == '\r')) {
			break;
		    }
		}
		if (!(flags & TK_IGNORE_TABS)) {
		    if (*special == '\t') {
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
2062
2063
2064
2065
2066
2067
2068

2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085

2086
2087
2088
2089
2090
2091
2092
2093







-
+
















-
+







			bytesThisChunk, curX, newX, baseline);

		start += bytesThisChunk;
		curX = newX;
	    }
	}

	if ((start == special) && (special < end)) {
	if ((start == special) && (special < endp)) {
	    /*
	     * Handle the special character.
	     *
	     * INTL: Special will be pointing at a 7-bit character so we can
	     * safely treat it as a single byte.
	     */

	    chunkPtr = NULL;
	    if (*special == '\t') {
		newX = curX + fontPtr->tabWidth;
		newX -= newX % fontPtr->tabWidth;
		NewChunk(&layoutPtr, &maxChunks, start, 1, curX, newX,
			baseline)->numDisplayChars = -1;
		start++;
		curX = newX;
		flags &= ~TK_AT_LEAST_ONE;
		if ((start < end) &&
		if ((start < endp) &&
			((wrapLength <= 0) || (newX <= wrapLength))) {
		    /*
		     * More chars can still fit on this line.
		     */

		    continue;
		}
2099
2100
2101
2102
2103
2104
2105
2106

2107
2108
2109
2110
2111
2112
2113
2101
2102
2103
2104
2105
2106
2107

2108
2109
2110
2111
2112
2113
2114
2115







-
+








	/*
	 * No more characters are going to go on this line, either because no
	 * more characters can fit or there are no more characters left.
	 * Consume all extra spaces at end of line.
	 */

	while ((start < end) && isspace(UCHAR(*start))) { /* INTL: ISO space */
	while ((start < endp) && isspace(UCHAR(*start))) { /* INTL: ISO space */
	    if (!(flags & TK_IGNORE_NEWLINES)) {
		if ((*start == '\n') || (*start == '\r')) {
		    break;
		}
	    }
	    if (!(flags & TK_IGNORE_TABS)) {
		if (*start == '\t') {
2287
2288
2289
2290
2291
2292
2293
2294

2295
2296
2297
2298
2299




2300
2301
2302
2303
2304
2305
2306
2289
2290
2291
2292
2293
2294
2295

2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312







-
+





+
+
+
+







    GC gc,			/* Graphics context to use for drawing
				 * text. */
    Tk_TextLayout layout,	/* Layout information, from a previous call to
				 * Tk_ComputeTextLayout(). */
    int x, int y,		/* Upper-left hand corner of rectangle in
				 * which to draw (pixels). */
    int firstChar,		/* The index of the first character to draw
				 * from the given text item. 0 specfies the
				 * from the given text item. 0 specifies the
				 * beginning. */
    int lastChar)		/* The index just after the last character to
				 * draw from the given text item. A number < 0
				 * means to draw all characters. */
{
#if 0
    /* Use TkDrawAngledTextLayout() implementation - testing purposes at this point */
    TkDrawAngledTextLayout(display, drawable, gc, layout, x, y, 0.0, firstChar, lastChar);
#else
    TextLayout *layoutPtr = (TextLayout *) layout;
    int i, numDisplayChars, drawX;
    const char *firstByte, *lastByte;
    LayoutChunk *chunkPtr;

    if (layoutPtr == NULL) {
	return;
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
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







+
+
+
+
+
+


+








+














-
+







		Tk_MeasureChars(layoutPtr->tkfont, chunkPtr->start,
			firstByte - chunkPtr->start, -1, 0, &drawX);
	    }
	    if (lastChar < numDisplayChars) {
		numDisplayChars = lastChar;
	    }
	    lastByte = Tcl_UtfAtIndex(chunkPtr->start, numDisplayChars);
#ifdef TK_DRAW_IN_CONTEXT
	    TkpDrawCharsInContext(display, drawable, gc, layoutPtr->tkfont,
		    chunkPtr->start, chunkPtr->numBytes,
		    firstByte - chunkPtr->start, lastByte - firstByte,
		    x+chunkPtr->x, y+chunkPtr->y);
#else /* !TK_DRAW_IN_CONTEXT */
	    Tk_DrawChars(display, drawable, gc, layoutPtr->tkfont, firstByte,
		    lastByte - firstByte, x+chunkPtr->x+drawX, y+chunkPtr->y);
#endif /* TK_DRAW_IN_CONTEXT */
	}
	firstChar -= chunkPtr->numChars;
	lastChar -= chunkPtr->numChars;
	if (lastChar <= 0) {
	    break;
	}
	chunkPtr++;
    }
#endif /* Use TkDrawAngledTextLayout() implementation */
}

void
TkDrawAngledTextLayout(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context to use for drawing
				 * text. */
    Tk_TextLayout layout,	/* Layout information, from a previous call to
				 * Tk_ComputeTextLayout(). */
    int x, int y,		/* Upper-left hand corner of rectangle in
				 * which to draw (pixels). */
    double angle,
    int firstChar,		/* The index of the first character to draw
				 * from the given text item. 0 specfies the
				 * from the given text item. 0 specifies the
				 * beginning. */
    int lastChar)		/* The index just after the last character to
				 * draw from the given text item. A number < 0
				 * means to draw all characters. */
{
    TextLayout *layoutPtr = (TextLayout *) layout;
    int i, numDisplayChars, drawX;
2384
2385
2386
2387
2388
2389
2390















2391
2392
2393
2394
2395
2396
2397
2398
2399
2400

2401
2402
2403
2404
2405
2406
2407
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437







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










+







		Tk_MeasureChars(layoutPtr->tkfont, chunkPtr->start,
			firstByte - chunkPtr->start, -1, 0, &drawX);
	    }
	    if (lastChar < numDisplayChars) {
		numDisplayChars = lastChar;
	    }
	    lastByte = Tcl_UtfAtIndex(chunkPtr->start, numDisplayChars);
#ifdef TK_DRAW_IN_CONTEXT
	    dx = cosA * (chunkPtr->x) + sinA * (chunkPtr->y);
	    dy = -sinA * (chunkPtr->x) + cosA * (chunkPtr->y);
	    if (angle == 0.0) {
		TkpDrawCharsInContext(display, drawable, gc,
			layoutPtr->tkfont, chunkPtr->start, chunkPtr->numBytes,
			firstByte - chunkPtr->start, lastByte - firstByte,
			(int)(x + dx), (int)(y + dy));
	    } else {
		TkpDrawAngledCharsInContext(display, drawable, gc,
			layoutPtr->tkfont, chunkPtr->start, chunkPtr->numBytes,
			firstByte - chunkPtr->start, lastByte - firstByte,
			x+dx, y+dy, angle);
	    }
#else /* !TK_DRAW_IN_CONTEXT */
	    dx = cosA * (chunkPtr->x + drawX) + sinA * (chunkPtr->y);
	    dy = -sinA * (chunkPtr->x + drawX) + cosA * (chunkPtr->y);
	    if (angle == 0.0) {
		Tk_DrawChars(display, drawable, gc, layoutPtr->tkfont,
			firstByte, lastByte - firstByte,
			(int)(x + dx), (int)(y + dy));
	    } else {
		TkDrawAngledChars(display, drawable, gc, layoutPtr->tkfont,
			firstByte, lastByte - firstByte, x+dx, y+dy, angle);
	    }
#endif /* TK_DRAW_IN_CONTEXT */
	}
	firstChar -= chunkPtr->numChars;
	lastChar -= chunkPtr->numChars;
	if (lastChar <= 0) {
	    break;
	}
	chunkPtr++;
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
2733
2734
2735
2736
2737
2738
2739

2740
2741
2742
2743
2744
2745
2746
2747
2748
2749

2750
2751
2752
2753
2754
2755
2756







-
+









-







				 * 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;
    LayoutChunk *chunkPtr = layoutPtr->chunks;
    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;
3311
3312
3313
3314
3315
3316
3317
3318

3319
3320
3321
3322
3323
3324
3325
3340
3341
3342
3343
3344
3345
3346

3347
3348
3349
3350
3351
3352
3353
3354







-
+








	    if (ch > 0xffff) {
		goto noMapping;
	    }
	    sprintf(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 {
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
3395
3396
3397
3398
3399
3400
3401

3402
3403
3404
3405
3406
3407
3408
3409
3410
3411

3412
3413
3414
3415
3416
3417
3418







-
+









-







 *
 *---------------------------------------------------------------------------
 */

static int
ConfigAttributesObj(
    Tcl_Interp *interp,		/* Interp for error return. */
    Tk_Window tkwin,		/* For display on which font will be used. */
    TCL_UNUSED(Tk_Window),	/* For display on which font will be used. */
    int objc,			/* Number of elements in argv. */
    Tcl_Obj *const objv[],	/* Command line options. */
    TkFontAttributes *faPtr)	/* Font attributes structure whose fields are
				 * to be modified. Structure must already be
				 * properly initialized. */
{
    int i, n, index;
    Tcl_Obj *optionPtr, *valuePtr;
    const char *value;
    (void)tkwin;

    for (i = 0; i < objc; i += 2) {
	optionPtr = objv[i];

	if (Tcl_GetIndexFromObj(interp, optionPtr, fontOpt, "option", 1,
		&index) != TCL_OK) {
	    return TCL_ERROR;
3538
3539
3540
3541
3542
3543
3544



















































3545
3546
3547
3548
3549
3550
3551
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







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







	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
3742
3743
3744
3745
3746
3747
3748
3749

3750
3751
3752
3753
3754
3755
3756
3821
3822
3823
3824
3825
3826
3827

3828
3829
3830
3831
3832
3833
3834
3835







-
+







    int maxChunks, numChars;
    size_t s;

    layoutPtr = *layoutPtrPtr;
    maxChunks = *maxPtr;
    if (layoutPtr->numChunks == maxChunks) {
	maxChunks *= 2;
	s = sizeof(TextLayout) + ((maxChunks - 1) * sizeof(LayoutChunk));
	s = offsetof(TextLayout, chunks) + (maxChunks * sizeof(LayoutChunk));
	layoutPtr = (TextLayout *)ckrealloc(layoutPtr, s);

	*layoutPtrPtr = layoutPtr;
	*maxPtr = maxChunks;
    }
    numChars = Tcl_NumUtfChars(start, numBytes);
    chunkPtr = &layoutPtr->chunks[layoutPtr->numChunks];

Changes to generic/tkFont.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







-
+







/*
 * tkFont.h --
 *
 *	Declarations for interfaces between the generic and platform-specific
 *	parts of the font package. This information is not visible outside of
 *	the font package.
 *
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 * Copyright © 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 _TKFONT
#define _TKFONT

Changes to generic/tkFrame.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







-
-
+
+







/*
 * tkFrame.c --
 *
 *	This module implements "frame", "labelframe" and "toplevel" widgets
 *	for the Tk toolkit. Frames are windows with a background color and
 *	possibly a 3-D effect, but not much else in the way of attributes.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "default.h"
340
341
342
343
344
345
346
347

348
349
350
351
352
353
354
340
341
342
343
344
345
346

347
348
349
350
351
352
353
354







-
+







			    Tk_Image bgimg, int bgtile);
static void		FrameBgImageProc(ClientData clientData,
			    int x, int y, int width, int height,
			    int imgWidth, int imgHeight);
static void		FrameCmdDeletedProc(ClientData clientData);
static void		FrameEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		FrameLostSlaveProc(ClientData clientData,
static void		FrameLostContentProc(ClientData clientData,
			    Tk_Window tkwin);
static void		FrameRequestProc(ClientData clientData,
			    Tk_Window tkwin);
static void		FrameStructureProc(ClientData clientData,
			    XEvent *eventPtr);
static int		FrameWidgetObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
372
373
374
375
376
377
378
379

380
381
382
383
384
385
386
372
373
374
375
376
377
378

379
380
381
382
383
384
385
386







-
+







 * The structure below defines the official type record for the labelframe's
 * geometry manager:
 */

static const Tk_GeomMgr frameGeomType = {
    "labelframe",		/* name */
    FrameRequestProc,		/* requestProc */
    FrameLostSlaveProc		/* lostSlaveProc */
    FrameLostContentProc		/* lostContentProc */
};

/*
 *--------------------------------------------------------------
 *
 * Tk_FrameObjCmd, Tk_ToplevelObjCmd, Tk_LabelframeObjCmd --
 *
543
544
545
546
547
548
549
550

551
552
553
554
555
556
557
543
544
545
546
547
548
549

550
551
552
553
554
555
556
557







-
+







     * 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)
728
729
730
731
732
733
734
735

736
737
738
739
740
741
742
728
729
730
731
732
733
734

735
736
737
738
739
740
741
742







-
+







	    goto error;
	}
	TkpMakeContainer(framePtr->tkwin);
    }
    if (type == TYPE_TOPLEVEL) {
	Tcl_DoWhenIdle(MapFrame, framePtr);
    }
    Tcl_SetObjResult(interp, TkNewWindowObj(newWin));
    Tcl_SetObjResult(interp, Tk_NewWindowObj(newWin));
    return TCL_OK;

  error:
    if (newWin != NULL) {
	Tk_DestroyWindow(newWin);
    }
    return TCL_ERROR;
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
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







-
+


















-
+







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







-
+


-
+





-
+





-
-
+
+

-
+








    FrameWorldChanged(framePtr);
}

/*
 *--------------------------------------------------------------
 *
 * FrameLostSlaveProc --
 * FrameLostContentProc --
 *
 *	This function is invoked by Tk whenever some other geometry claims
 *	control over a slave that used to be managed by us.
 *	control over a content window that used to be managed by us.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Forgets all frame-related information about the slave.
 *	Forgets all frame-related information about the content window.
 *
 *--------------------------------------------------------------
 */

static void
FrameLostSlaveProc(
    ClientData clientData,	/* Frame structure for slave window that was
FrameLostContentProc(
    ClientData clientData,	/* Frame structure for content window window that was
				 * stolen away. */
    Tk_Window tkwin)		/* Tk's handle for the slave window. */
    Tk_Window tkwin)		/* Tk's handle for the content window window. */
{
    Frame *framePtr = (Frame *)clientData;
    Labelframe *labelframePtr = (Labelframe *)clientData;
    (void)tkwin;

    /*
     * This should only happen in a labelframe but it doesn't hurt to be

Changes to generic/tkGC.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






-
-
+
+







/*
 * tkGC.c --
 *
 *	This file maintains a database of read-only graphics contexts for the
 *	Tk toolkit, in order to allow GC's to be shared.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994 Sun Microsystems, Inc.
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

Changes to generic/tkGeometry.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
1
2
3
4
5
6


7
8
9
10
11
12
13
14
15
16
17


18
19
20
21



22
23
24
25





26
27
28
29
30
31


32
33
34
35

36
37
38
39

40
41
42
43
44
45
46
47



48
49
50
51
52
53
54
55
56

57
58

59
60
61
62
63
64
65
66
67

68
69
70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97


98
99
100
101
102
103
104
105
106






-
-
+
+









-
-
+
+


-
-
-
+
+
+

-
-
-
-
-
+
+
+
+
+

-
-
+
+


-
+



-
+







-
-
-
+
+
+






-
+

-
+








-
+









-
+



















-
-
+
+







/*
 * tkGeometry.c --
 *
 *	This file contains generic Tk code for geometry management (stuff
 *	that's used by all geometry managers).
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1995 Sun Microsystems, Inc.
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

/*
 * Data structures of the following type are used by Tk_MaintainGeometry. For
 * each slave managed by Tk_MaintainGeometry, there is one of these structures
 * associated with its master.
 * each content managed by Tk_MaintainGeometry, there is one of these structures
 * associated with its container.
 */

typedef struct MaintainSlave {
    Tk_Window slave;		/* The slave window being positioned. */
    Tk_Window master;		/* The master that determines slave's
typedef struct MaintainContent {
    Tk_Window content;		/* The content window being positioned. */
    Tk_Window container;		/* The container that determines content's
				 * position; it must be a descendant of
				 * slave's parent. */
    int x, y;			/* Desired position of slave relative to
				 * master. */
    int width, height;		/* Desired dimensions of slave. */
    struct MaintainSlave *nextPtr;
				 * content's parent. */
    int x, y;			/* Desired position of content relative to
				 * container. */
    int width, height;		/* Desired dimensions of content. */
    struct MaintainContent *nextPtr;
				/* Next in list of Maintains associated with
				 * master. */
} MaintainSlave;
				 * container. */
} MaintainContent;

/*
 * For each window that has been specified as a master to Tk_MaintainGeometry,
 * For each window that has been specified as a content to Tk_MaintainGeometry,
 * there is a structure of the following type:
 */

typedef struct MaintainMaster {
typedef struct MaintainContainer {
    Tk_Window ancestor;		/* The lowest ancestor of this window for
				 * which we have *not* created a
				 * StructureNotify handler. May be the same as
				 * the window itself. */
    int checkScheduled;		/* Non-zero means that there is already a call
				 * to MaintainCheckProc scheduled as an idle
				 * handler. */
    MaintainSlave *slavePtr;	/* First in list of all slaves associated with
				 * this master. */
} MaintainMaster;
    MaintainContent *contentPtr;	/* First in list of all content associated with
				 * this container. */
} MaintainContainer;

/*
 * Prototypes for static procedures in this file:
 */

static void		MaintainCheckProc(ClientData clientData);
static void		MaintainMasterProc(ClientData clientData,
static void		MaintainContainerProc(ClientData clientData,
			    XEvent *eventPtr);
static void		MaintainSlaveProc(ClientData clientData,
static void		MaintainContentProc(ClientData clientData,
			    XEvent *eventPtr);

/*
 *--------------------------------------------------------------
 *
 * Tk_ManageGeometry --
 *
 *	Arrange for a particular procedure to manage the geometry of a given
 *	slave window.
 *	content window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Proc becomes the new geometry manager for tkwin, replacing any
 *	previous geometry manager. The geometry manager will be notified (by
 *	calling procedures in *mgrPtr) when interesting things happen in the
 *	future. If there was an existing geometry manager for tkwin different
 *	from the new one, it is notified by calling its lostSlaveProc.
 *	from the new one, it is notified by calling its lostContentProc.
 *
 *--------------------------------------------------------------
 */

void
Tk_ManageGeometry(
    Tk_Window tkwin,		/* Window whose geometry is to be managed by
				 * proc. */
    const Tk_GeomMgr *mgrPtr,	/* Static structure describing the geometry
				 * manager. This structure must never go
				 * away. */
    ClientData clientData)	/* Arbitrary one-word argument to pass to
				 * geometry manager procedures. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    if ((winPtr->geomMgrPtr != NULL) && (mgrPtr != NULL)
	    && ((winPtr->geomMgrPtr != mgrPtr)
		|| (winPtr->geomData != clientData))
	    && (winPtr->geomMgrPtr->lostSlaveProc != NULL)) {
	winPtr->geomMgrPtr->lostSlaveProc(winPtr->geomData, tkwin);
	    && (winPtr->geomMgrPtr->lostContentProc != NULL)) {
	winPtr->geomMgrPtr->lostContentProc(winPtr->geomData, tkwin);
    }

    winPtr->geomMgrPtr = mgrPtr;
    winPtr->geomData = clientData;
}

/*
214
215
216
217
218
219
220
221

222
223
224
225
226
227
228
214
215
216
217
218
219
220

221
222
223
224
225
226
227
228







-
+







    }
    if (bottom != winPtr->internalBorderBottom) {
	winPtr->internalBorderBottom = bottom;
	changed = 1;
    }

    /*
     * All the slaves for which this is the master window must now be
     * All the content for which this is the container window must now be
     * repositioned to take account of the new internal border width. To
     * signal all the geometry managers to do this, trigger a ConfigureNotify
     * event. This will cause geometry managers to recompute everything.
     */

    if (changed) {
	TkDoConfigureNotify(winPtr);
299
300
301
302
303
304
305
306

307
308

309
310
311
312
313
314
315

316
317
318
319
320
321

322
323

324
325

326
327
328
329
330

331
332
333
334
335
336
337
338



339
340
341
342
343
344
345


346
347
348
349
350
351
352

353
354

355
356
357
358
359
360
361

362
363
364
365
366
367
368


369
370

371
372
373
374
375

376
377

378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395






396
397
398
399
400
401
402
403

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





419
420
421
422


423
424
425

426
427

428
429
430

431
432

433
434
435
436
437
438

439
440
441
442


443
444
445
446
447


448
449
450
451
452
453
454
455
456
457
458

459
460
461
462

463
464

465
466

467
468
469
470
471
472





473
474
475
476

477
478
479
480
481
482
483




484
485
486
487
488
489
490
491
492







493
494
495
496
497
498



499
500
501

502
503

504
505
506


507
508
509
510
511
512
513
514
515
516
517
518
519





520
521

522
523
524
525
526
527
528
529
530





531
532
533

534
535

536
537
538
539
540
541
542
543
544
545
546
547
548
549
550

551
552
553
554
555
556
557
558



559
560
561
562
563
564
565
566
567



568
569
570
571


572
573

574
575

576
577
578

579
580

581
582
583
584
585
586
587
588
589
590
591
592
593


594
595

596
597
598
599
600
601
602




603
604
605
606



607
608
609
610


611
612
613
614
615
616
617
618
619
620






621
622
623


624
625
626
627
628
629


630
631
632

633
634
635
636
637
638
639

640
641
642

643
644
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
299
300
301
302
303
304
305

306
307

308
309
310
311
312
313
314

315
316
317
318
319
320

321
322

323
324

325
326
327
328
329

330
331
332
333
334
335



336
337
338
339
340
341
342
343


344
345
346
347
348
349
350
351

352
353

354
355
356
357
358
359
360

361
362
363
364
365
366


367
368
369

370
371
372
373
374

375
376

377
378
379
380
381
382
383
384
385
386
387
388
389






390
391
392
393
394
395
396
397
398
399
400
401
402

403
404
405
406
407
408
409
410
411
412
413





414
415
416
417
418
419
420


421
422
423
424

425
426

427
428


429
430

431
432
433
434
435
436

437
438
439


440
441
442
443
444


445
446
447
448
449
450
451
452
453
454
455
456

457
458
459
460

461
462

463
464

465
466





467
468
469
470
471
472
473
474

475
476
477
478




479
480
481
482
483
484







485
486
487
488
489
490
491
492
493
494



495
496
497
498
499

500
501

502
503


504
505
506
507
508
509
510
511
512
513





514
515
516
517
518
519

520
521
522
523
524





525
526
527
528
529
530
531

532
533

534
535
536
537
538
539
540
541
542
543
544
545
546
547
548

549
550
551
552
553
554



555
556
557
558
559
560
561
562
563



564
565
566
567
568


569
570
571

572
573

574
575


576
577

578
579
580
581
582
583
584
585
586
587
588
589


590
591
592

593
594
595
596




597
598
599
600
601



602
603
604
605
606


607
608
609
610
611
612






613
614
615
616
617
618
619


620
621
622
623
624
625


626
627
628
629

630
631
632
633
634
635
636

637
638
639

640
641
642
643
644
645
646
647
648

649
650
651
652
653
654
655



656
657
658
659
660


661
662
663
664
665
666
667



668
669
670
671
672
673


674
675
676
677
678
679
680


681
682
683
684

685
686
687
688
689
690
691
692

693
694
695

696
697
698
699
700
701
702
703

704
705
706
707
708
709



710
711
712
713
714

715
716
717

718
719
720
721
722
723
724
725
726
727




728
729
730
731
732
733
734
735
736

737
738
739
740
741
742
743


744
745
746


747
748
749
750
751






752
753
754
755
756
757
758

759
760
761
762
763



764
765
766
767
768

769
770

771
772
773
774
775
776
777
778







-
+

-
+






-
+





-
+

-
+

-
+




-
+





-
-
-
+
+
+





-
-
+
+






-
+

-
+






-
+





-
-
+
+

-
+




-
+

-
+












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







-
+










-
-
-
-
-
+
+
+
+
+


-
-
+
+


-
+

-
+

-
-
+

-
+





-
+


-
-
+
+



-
-
+
+










-
+



-
+

-
+

-
+

-
-
-
-
-
+
+
+
+
+



-
+



-
-
-
-
+
+
+
+


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



-
-
-
+
+
+


-
+

-
+

-
-
+
+








-
-
-
-
-
+
+
+
+
+

-
+




-
-
-
-
-
+
+
+
+
+


-
+

-
+














-
+





-
-
-
+
+
+






-
-
-
+
+
+


-
-
+
+

-
+

-
+

-
-
+

-
+











-
-
+
+

-
+



-
-
-
-
+
+
+
+

-
-
-
+
+
+


-
-
+
+




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

-
-
+
+




-
-
+
+


-
+






-
+


-
+








-
+






-
-
-
+
+
+


-
-
+
+





-
-
-
+
+
+



-
-
+
+





-
-
+
+


-
+







-
+


-
+







-
+





-
-
-
+
+
+


-
+


-
+









-
-
-
-
+
+
+
+





-
+






-
-
+
+

-
-
+
+



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

-
+




-
-
-
+
+
+


-
+

-
+








    Tk_ResizeWindow(tkwin, Tk_Width(tkwin), Tk_Height(tkwin));
}

/*
 *----------------------------------------------------------------------
 *
 * TkSetGeometryMaster --
 * TkSetGeometryContainer --
 *
 *	Set a geometry master for this window. Only one master may own
 *	Set a geometry container for this window. Only one container may own
 *	a window at any time.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	The geometry master is recorded for the window.
 *	The geometry container is recorded for the window.
 *
 *----------------------------------------------------------------------
 */

int
TkSetGeometryMaster(
TkSetGeometryContainer(
    Tcl_Interp *interp,		/* Current interpreter, for error. */
    Tk_Window tkwin,		/* Window that will have geometry master
    Tk_Window tkwin,		/* Window that will have geometry container
				 * set. */
    const char *master)		/* The master identity. */
    const char *name)		/* The name of the geometry manager. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    if (winPtr->geomMgrName != NULL &&
	    strcmp(winPtr->geomMgrName, master) == 0) {
	    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 which already"
		    " has slaves managed by %s",
		    master, Tk_PathName(tkwin), winPtr->geomMgrName));
		    "cannot use geometry manager %s inside %s because"
		    " %s is already managing it's content windows",
		    name, Tk_PathName(tkwin), winPtr->geomMgrName));
	    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "FIGHT", NULL);
	}
	return TCL_ERROR;
    }

    winPtr->geomMgrName = (char *)ckalloc(strlen(master) + 1);
    strcpy(winPtr->geomMgrName, master);
    winPtr->geomMgrName = (char *)ckalloc(strlen(name) + 1);
    strcpy(winPtr->geomMgrName, name);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkFreeGeometryMaster --
 * TkFreeGeometryContainer --
 *
 *	Remove a geometry master for this window. Only one master may own
 *	Remove a geometry container for this window. Only one container may own
 *	a window at any time.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The geometry master is cleared for the window.
 *	The geometry container is cleared for the window.
 *
 *----------------------------------------------------------------------
 */

void
TkFreeGeometryMaster(
    Tk_Window tkwin,		/* Window that will have geometry master
TkFreeGeometryContainer(
    Tk_Window tkwin,		/* Window that will have geometry container
				 * cleared. */
    const char *master)		/* The master identity. */
    const char *name)		/* The name of the geometry manager. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    if (winPtr->geomMgrName != NULL &&
	    strcmp(winPtr->geomMgrName, master) != 0) {
	    strcmp(winPtr->geomMgrName, name) != 0) {
	Tcl_Panic("Trying to free %s from geometry manager %s",
		winPtr->geomMgrName, master);
		winPtr->geomMgrName, name);
    }
    if (winPtr->geomMgrName != NULL) {
	ckfree(winPtr->geomMgrName);
	winPtr->geomMgrName = NULL;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MaintainGeometry --
 *
 *	This procedure is invoked by geometry managers to handle slaves whose
 *	master's are not their parents. It translates the desired geometry for
 *	the slave into the coordinate system of the parent and respositions
 *	the slave if it isn't already at the right place. Furthermore, it sets
 *	up event handlers so that if the master (or any of its ancestors up to
 *	the slave's parent) is mapped, unmapped, or moved, then the slave will
 *	This procedure is invoked by geometry managers to handle content whose
 *	container's are not their parents. It translates the desired geometry for
 *	the content into the coordinate system of the parent and respositions
 *	the content if it isn't already at the right place. Furthermore, it sets
 *	up event handlers so that if the container (or any of its ancestors up to
 *	the content's parent) is mapped, unmapped, or moved, then the content will
 *	be adjusted to match.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Event handlers are created and state is allocated to keep track of
 *	slave. Note: if slave was already managed for master by
 *	content. Note: if content was already managed for container by
 *	Tk_MaintainGeometry, then the previous information is replaced with
 *	the new information. The caller must eventually call
 *	Tk_UnmaintainGeometry to eliminate the correspondence (or, the state
 *	is automatically freed when either window is destroyed).
 *
 *----------------------------------------------------------------------
 */

void
Tk_MaintainGeometry(
    Tk_Window slave,		/* Slave for geometry management. */
    Tk_Window master,		/* Master for slave; must be a descendant of
				 * slave's parent. */
    int x, int y,		/* Desired position of slave within master. */
    int width, int height)	/* Desired dimensions for slave. */
    Tk_Window window,		/* Window for geometry management. */
    Tk_Window container,		/* Container for window; must be a descendant of
				 * window's parent. */
    int x, int y,		/* Desired position of window within container. */
    int width, int height)	/* Desired dimensions for window. */
{
    Tcl_HashEntry *hPtr;
    MaintainMaster *masterPtr;
    MaintainSlave *slavePtr;
    MaintainContainer *containerPtr;
    MaintainContent *contentPtr;
    int isNew, map;
    Tk_Window ancestor, parent;
    TkDisplay *dispPtr = ((TkWindow *) master)->dispPtr;
    TkDisplay *dispPtr = ((TkWindow *) container)->dispPtr;

    ((TkWindow *)slave)->maintainerPtr = (TkWindow *)master;
    ((TkWindow *)window)->maintainerPtr = (TkWindow *)container;

    ((TkWindow *)slave)->maintainerPtr = (TkWindow *)master;
    if (master == Tk_Parent(slave)) {
    if (container == Tk_Parent(window)) {
	/*
	 * If the slave is a direct descendant of the master, don't bother
	 * If the window is a direct descendant of the container, don't bother
	 * setting up the extra infrastructure for management, just make a
	 * call to Tk_MoveResizeWindow; the parent/child relationship will
	 * take care of the rest.
	 */

	Tk_MoveResizeWindow(slave, x, y, width, height);
	Tk_MoveResizeWindow(window, x, y, width, height);

	/*
	 * Map the slave if the master is already mapped; otherwise, wait
	 * until the master is mapped later (in which case mapping the slave
	 * Map the window if the container is already mapped; otherwise, wait
	 * until the container is mapped later (in which case mapping the window
	 * is taken care of elsewhere).
	 */

	if (Tk_IsMapped(master)) {
	    Tk_MapWindow(slave);
	if (Tk_IsMapped(container)) {
	    Tk_MapWindow(window);
	}
	return;
    }

    if (!dispPtr->geomInit) {
	dispPtr->geomInit = 1;
	Tcl_InitHashTable(&dispPtr->maintainHashTable, TCL_ONE_WORD_KEYS);
    }

    /*
     * See if there is already a MaintainMaster structure for the master; if
     * See if there is already a MaintainContainer structure for the container; if
     * not, then create one.
     */

    parent = Tk_Parent(slave);
    parent = Tk_Parent(window);
    hPtr = Tcl_CreateHashEntry(&dispPtr->maintainHashTable,
	    (char *) master, &isNew);
	    (char *) container, &isNew);
    if (!isNew) {
	masterPtr = (MaintainMaster *)Tcl_GetHashValue(hPtr);
	containerPtr = (MaintainContainer *)Tcl_GetHashValue(hPtr);
    } else {
	masterPtr = (MaintainMaster *)ckalloc(sizeof(MaintainMaster));
	masterPtr->ancestor = master;
	masterPtr->checkScheduled = 0;
	masterPtr->slavePtr = NULL;
	Tcl_SetHashValue(hPtr, masterPtr);
	containerPtr = (MaintainContainer *)ckalloc(sizeof(MaintainContainer));
	containerPtr->ancestor = container;
	containerPtr->checkScheduled = 0;
	containerPtr->contentPtr = NULL;
	Tcl_SetHashValue(hPtr, containerPtr);
    }

    /*
     * Create a MaintainSlave structure for the slave if there isn't already
     * Create a MaintainContent structure for the window if there isn't already
     * one.
     */

    for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
	    slavePtr = slavePtr->nextPtr) {
	if (slavePtr->slave == slave) {
	    goto gotSlave;
    for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
	    contentPtr = contentPtr->nextPtr) {
	if (contentPtr->content == window) {
	    goto gotContent;
	}
    }
    slavePtr = (MaintainSlave *)ckalloc(sizeof(MaintainSlave));
    slavePtr->slave = slave;
    slavePtr->master = master;
    slavePtr->nextPtr = masterPtr->slavePtr;
    masterPtr->slavePtr = slavePtr;
    Tk_CreateEventHandler(slave, StructureNotifyMask, MaintainSlaveProc,
	    slavePtr);
    contentPtr = (MaintainContent *)ckalloc(sizeof(MaintainContent));
    contentPtr->content = window;
    contentPtr->container = container;
    contentPtr->nextPtr = containerPtr->contentPtr;
    containerPtr->contentPtr = contentPtr;
    Tk_CreateEventHandler(window, StructureNotifyMask, MaintainContentProc,
	    contentPtr);

    /*
     * Make sure that there are event handlers registered for all the windows
     * between master and slave's parent (including master but not slave's
     * parent). There may already be handlers for master and some of its
     * ancestors (masterPtr->ancestor tells how many).
     * between container and windows's parent (including container but not window's
     * parent). There may already be handlers for container and some of its
     * ancestors (containerPtr->ancestor tells how many).
     */

    for (ancestor = master; ancestor != parent;
    for (ancestor = container; ancestor != parent;
	    ancestor = Tk_Parent(ancestor)) {
	if (ancestor == masterPtr->ancestor) {
	if (ancestor == containerPtr->ancestor) {
	    Tk_CreateEventHandler(ancestor, StructureNotifyMask,
		    MaintainMasterProc, masterPtr);
	    masterPtr->ancestor = Tk_Parent(ancestor);
		    MaintainContainerProc, containerPtr);
	    containerPtr->ancestor = Tk_Parent(ancestor);
	}
    }

    /*
     * Fill in up-to-date information in the structure, then update the window
     * if it's not currently in the right place or state.
     */

  gotSlave:
    slavePtr->x = x;
    slavePtr->y = y;
    slavePtr->width = width;
    slavePtr->height = height;
  gotContent:
    contentPtr->x = x;
    contentPtr->y = y;
    contentPtr->width = width;
    contentPtr->height = height;
    map = 1;
    for (ancestor = slavePtr->master; ; ancestor = Tk_Parent(ancestor)) {
    for (ancestor = contentPtr->container; ; ancestor = Tk_Parent(ancestor)) {
	if (!Tk_IsMapped(ancestor) && (ancestor != parent)) {
	    map = 0;
	}
	if (ancestor == parent) {
	    if ((x != Tk_X(slavePtr->slave))
		    || (y != Tk_Y(slavePtr->slave))
		    || (width != Tk_Width(slavePtr->slave))
		    || (height != Tk_Height(slavePtr->slave))) {
		Tk_MoveResizeWindow(slavePtr->slave, x, y, width, height);
	    if ((x != Tk_X(contentPtr->content))
		    || (y != Tk_Y(contentPtr->content))
		    || (width != Tk_Width(contentPtr->content))
		    || (height != Tk_Height(contentPtr->content))) {
		Tk_MoveResizeWindow(contentPtr->content, x, y, width, height);
	    }
	    if (map) {
		Tk_MapWindow(slavePtr->slave);
		Tk_MapWindow(contentPtr->content);
	    } else {
		Tk_UnmapWindow(slavePtr->slave);
		Tk_UnmapWindow(contentPtr->content);
	    }
	    break;
	}
	x += Tk_X(ancestor) + Tk_Changes(ancestor)->border_width;
	y += Tk_Y(ancestor) + Tk_Changes(ancestor)->border_width;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_UnmaintainGeometry --
 *
 *	This procedure cancels a previous Tk_MaintainGeometry call, so that
 *	the relationship between slave and master is no longer maintained.
 *	the relationship between window and container is no longer maintained.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The slave is unmapped and state is released, so that slave won't track
 *	master any more. If we weren't previously managing slave relative to
 *	master, then this procedure has no effect.
 *	The window is unmapped and state is released, so that window won't track
 *	container any more. If we weren't previously managing window relative to
 *	container, then this procedure has no effect.
 *
 *----------------------------------------------------------------------
 */

void
Tk_UnmaintainGeometry(
    Tk_Window slave,		/* Slave for geometry management. */
    Tk_Window master)		/* Master for slave; must be a descendant of
				 * slave's parent. */
    Tk_Window window,		/* WIndow for geometry management. */
    Tk_Window container)		/* Container for window; must be a descendant of
				 * window's parent. */
{
    Tcl_HashEntry *hPtr;
    MaintainMaster *masterPtr;
    MaintainSlave *slavePtr, *prevPtr;
    MaintainContainer *containerPtr;
    MaintainContent *contentPtr, *prevPtr;
    Tk_Window ancestor;
    TkDisplay *dispPtr = ((TkWindow *) slave)->dispPtr;
    TkDisplay *dispPtr = ((TkWindow *) window)->dispPtr;

    ((TkWindow *)slave)->maintainerPtr = NULL;
    ((TkWindow *)window)->maintainerPtr = NULL;

    ((TkWindow *)slave)->maintainerPtr = NULL;
    if (master == Tk_Parent(slave)) {
    if (container == Tk_Parent(window)) {
	/*
	 * If the slave is a direct descendant of the master,
	 * If the window is a direct descendant of the container,
	 * Tk_MaintainGeometry will not have set up any of the extra
	 * infrastructure. Don't even bother to look for it, just return.
	 */
	return;
    }

    if (!dispPtr->geomInit) {
	dispPtr->geomInit = 1;
	Tcl_InitHashTable(&dispPtr->maintainHashTable, TCL_ONE_WORD_KEYS);
    }

    if (!(((TkWindow *) slave)->flags & TK_ALREADY_DEAD)) {
	Tk_UnmapWindow(slave);
    if (!(((TkWindow *) window)->flags & TK_ALREADY_DEAD)) {
	Tk_UnmapWindow(window);
    }
    hPtr = Tcl_FindHashEntry(&dispPtr->maintainHashTable, master);
    hPtr = Tcl_FindHashEntry(&dispPtr->maintainHashTable, container);
    if (hPtr == NULL) {
	return;
    }
    masterPtr = (MaintainMaster *)Tcl_GetHashValue(hPtr);
    slavePtr = masterPtr->slavePtr;
    if (slavePtr->slave == slave) {
	masterPtr->slavePtr = slavePtr->nextPtr;
    containerPtr = (MaintainContainer *)Tcl_GetHashValue(hPtr);
    contentPtr = containerPtr->contentPtr;
    if (contentPtr->content == window) {
	containerPtr->contentPtr = contentPtr->nextPtr;
    } else {
	for (prevPtr = slavePtr, slavePtr = slavePtr->nextPtr; ;
		prevPtr = slavePtr, slavePtr = slavePtr->nextPtr) {
	    if (slavePtr == NULL) {
	for (prevPtr = contentPtr, contentPtr = contentPtr->nextPtr; ;
		prevPtr = contentPtr, contentPtr = contentPtr->nextPtr) {
	    if (contentPtr == NULL) {
		return;
	    }
	    if (slavePtr->slave == slave) {
		prevPtr->nextPtr = slavePtr->nextPtr;
	    if (contentPtr->content == window) {
		prevPtr->nextPtr = contentPtr->nextPtr;
		break;
	    }
	}
    }
    Tk_DeleteEventHandler(slavePtr->slave, StructureNotifyMask,
	    MaintainSlaveProc, slavePtr);
    ckfree(slavePtr);
    if (masterPtr->slavePtr == NULL) {
	if (masterPtr->ancestor != NULL) {
	    for (ancestor = master; ; ancestor = Tk_Parent(ancestor)) {
    Tk_DeleteEventHandler(contentPtr->content, StructureNotifyMask,
	    MaintainContentProc, contentPtr);
    ckfree(contentPtr);
    if (containerPtr->contentPtr == NULL) {
	if (containerPtr->ancestor != NULL) {
	    for (ancestor = container; ; ancestor = Tk_Parent(ancestor)) {
		Tk_DeleteEventHandler(ancestor, StructureNotifyMask,
			MaintainMasterProc, masterPtr);
		if (ancestor == masterPtr->ancestor) {
			MaintainContainerProc, containerPtr);
		if (ancestor == containerPtr->ancestor) {
		    break;
		}
	    }
	}
	if (masterPtr->checkScheduled) {
	    Tcl_CancelIdleCall(MaintainCheckProc, masterPtr);
	if (containerPtr->checkScheduled) {
	    Tcl_CancelIdleCall(MaintainCheckProc, containerPtr);
	}
	Tcl_DeleteHashEntry(hPtr);
	ckfree(masterPtr);
	ckfree(containerPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * MaintainMasterProc --
 * MaintainContainerProc --
 *
 *	This procedure is invoked by the Tk event dispatcher in response to
 *	StructureNotify events on the master or one of its ancestors, on
 *	StructureNotify events on the container or one of its ancestors, on
 *	behalf of Tk_MaintainGeometry.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	It schedules a call to MaintainCheckProc, which will eventually caused
 *	the postions and mapped states to be recalculated for all the
 *	maintained slaves of the master. Or, if the master window is being
 *	maintained windows of the container. Or, if the container window is being
 *	deleted then state is cleaned up.
 *
 *----------------------------------------------------------------------
 */

static void
MaintainMasterProc(
    ClientData clientData,	/* Pointer to MaintainMaster structure for the
				 * master window. */
MaintainContainerProc(
    ClientData clientData,	/* Pointer to MaintainContainer structure for the
				 * container window. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    MaintainMaster *masterPtr = (MaintainMaster *)clientData;
    MaintainSlave *slavePtr;
    MaintainContainer *containerPtr = (MaintainContainer *)clientData;
    MaintainContent *contentPtr;
    int done;

    if ((eventPtr->type == ConfigureNotify)
	    || (eventPtr->type == MapNotify)
	    || (eventPtr->type == UnmapNotify)) {
	if (!masterPtr->checkScheduled) {
	    masterPtr->checkScheduled = 1;
	    Tcl_DoWhenIdle(MaintainCheckProc, masterPtr);
	if (!containerPtr->checkScheduled) {
	    containerPtr->checkScheduled = 1;
	    Tcl_DoWhenIdle(MaintainCheckProc, containerPtr);
	}
    } else if (eventPtr->type == DestroyNotify) {
	/*
	 * Delete all of the state associated with this master, but be careful
	 * not to use masterPtr after the last slave is deleted, since its
	 * Delete all of the state associated with this container, but be careful
	 * not to use containerPtr after the last window is deleted, since its
	 * memory will have been freed.
	 */

	done = 0;
	do {
	    slavePtr = masterPtr->slavePtr;
	    if (slavePtr->nextPtr == NULL) {
	    contentPtr = containerPtr->contentPtr;
	    if (contentPtr->nextPtr == NULL) {
		done = 1;
	    }
	    Tk_UnmaintainGeometry(slavePtr->slave, slavePtr->master);
	    Tk_UnmaintainGeometry(contentPtr->content, contentPtr->container);
	} while (!done);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * MaintainSlaveProc --
 * MaintainContentProc --
 *
 *	This procedure is invoked by the Tk event dispatcher in response to
 *	StructureNotify events on a slave being managed by
 *	StructureNotify events on a window being managed by
 *	Tk_MaintainGeometry.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	If the event is a DestroyNotify event then the Maintain state and
 *	event handlers for this slave are deleted.
 *	event handlers for this window are deleted.
 *
 *----------------------------------------------------------------------
 */

static void
MaintainSlaveProc(
    ClientData clientData,	/* Pointer to MaintainSlave structure for
				 * master-slave pair. */
MaintainContentProc(
    ClientData clientData,	/* Pointer to MaintainContent structure for
				 * container-window pair. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    MaintainSlave *slavePtr = (MaintainSlave *)clientData;
    MaintainContent *contentPtr = (MaintainContent *)clientData;

    if (eventPtr->type == DestroyNotify) {
	Tk_UnmaintainGeometry(slavePtr->slave, slavePtr->master);
	Tk_UnmaintainGeometry(contentPtr->content, contentPtr->container);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * MaintainCheckProc --
 *
 *	This procedure is invoked by the Tk event dispatcher as an idle
 *	handler, when a master or one of its ancestors has been reconfigured,
 *	mapped, or unmapped. Its job is to scan all of the slaves for the
 *	master and reposition them, map them, or unmap them as needed to
 *	maintain their geometry relative to the master.
 *	handler, when a container or one of its ancestors has been reconfigured,
 *	mapped, or unmapped. Its job is to scan all of the windows for the
 *	container and reposition them, map them, or unmap them as needed to
 *	maintain their geometry relative to the container.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Slaves can get repositioned, mapped, or unmapped.
 *	Windows can get repositioned, mapped, or unmapped.
 *
 *----------------------------------------------------------------------
 */

static void
MaintainCheckProc(
    ClientData clientData)	/* Pointer to MaintainMaster structure for the
				 * master window. */
    ClientData clientData)	/* Pointer to MaintainContainer structure for the
				 * container window. */
{
    MaintainMaster *masterPtr = (MaintainMaster *)clientData;
    MaintainSlave *slavePtr;
    MaintainContainer *containerPtr = (MaintainContainer *)clientData;
    MaintainContent *contentPtr;
    Tk_Window ancestor, parent;
    int x, y, map;

    masterPtr->checkScheduled = 0;
    for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
	    slavePtr = slavePtr->nextPtr) {
	parent = Tk_Parent(slavePtr->slave);
	x = slavePtr->x;
	y = slavePtr->y;
    containerPtr->checkScheduled = 0;
    for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
	    contentPtr = contentPtr->nextPtr) {
	parent = Tk_Parent(contentPtr->content);
	x = contentPtr->x;
	y = contentPtr->y;
	map = 1;
	for (ancestor = slavePtr->master; ; ancestor = Tk_Parent(ancestor)) {
	for (ancestor = contentPtr->container; ; ancestor = Tk_Parent(ancestor)) {
	    if (!Tk_IsMapped(ancestor) && (ancestor != parent)) {
		map = 0;
	    }
	    if (ancestor == parent) {
		if ((x != Tk_X(slavePtr->slave))
			|| (y != Tk_Y(slavePtr->slave))) {
		    Tk_MoveWindow(slavePtr->slave, x, y);
		if ((x != Tk_X(contentPtr->content))
			|| (y != Tk_Y(contentPtr->content))) {
		    Tk_MoveWindow(contentPtr->content, x, y);
		}
		if (map) {
		    Tk_MapWindow(slavePtr->slave);
		    Tk_MapWindow(contentPtr->content);
		} else {
		    Tk_UnmapWindow(slavePtr->slave);
		    Tk_UnmapWindow(contentPtr->content);
		}
		break;
	    }
	    x += Tk_X(ancestor) + Tk_Changes(ancestor)->border_width;
	    y += Tk_Y(ancestor) + Tk_Changes(ancestor)->border_width;
	}
    }

Changes to generic/tkGet.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








-
-
+
+







/*
 * tkGet.c --
 *
 *	This file contains a number of "Tk_GetXXX" procedures, which parse
 *	text strings into useful forms for Tk. This file has the simpler
 *	functions, like Tk_GetDirection and Tk_GetUid. The more complex
 *	functions like Tk_GetColor are in separate files.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1991-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

489
490
491
492
493
494
495
496

497
498
499
500
501
502
503
504
505
506
507
489
490
491
492
493
494
495

496
497
498
499

500
501
502
503
504
505
506







-
+



-







 *	All information in the identifier table is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
FreeUidThreadExitProc(
    ClientData dummy)		/* Not used. */
    TCL_UNUSED(void *))
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)dummy;

    Tcl_DeleteHashTable(&tsdPtr->uidTable);
    tsdPtr->initialized = 0;
}

/*
 *----------------------------------------------------------------------
691
692
693
694
695
696
697





698
699
700
701
702
703
704
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708







+
+
+
+
+







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

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





-
-
+
+







/*
 * tkGrab.c --
 *
 *	This file provides functions that implement grabs for Tk.
 *
 * Copyright (c) 1992-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1992-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

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







-
+







	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
266
267
268
269
270
271
272

273
274
275
276
277
278
279
280
281

282
283
284
285
286
287
288
289







-
+








-
+







	    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, TkNewWindowObj((Tk_Window)
		Tcl_SetObjResult(interp, Tk_NewWindowObj((Tk_Window)
			dispPtr->eventualGrabWinPtr));
	    }
	} else {
	    Tcl_Obj *resultObj = Tcl_NewObj();

	    for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
		    dispPtr = dispPtr->nextPtr) {
		if (dispPtr->eventualGrabWinPtr != NULL) {
		    Tcl_ListObjAppendElement(NULL, resultObj, TkNewWindowObj(
		    Tcl_ListObjAppendElement(NULL, resultObj, Tk_NewWindowObj(
			    (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
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690







+
+
+











+







 *----------------------------------------------------------------------
 *
 * 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. */
768
769
770
771
772
773
774










775
776
777
778
779




780
781
782
783
784
785
786
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







+
+
+
+
+
+
+
+
+
+





+
+
+
+







	    if ((dispPtr->buttonWinPtr != NULL)
		    && (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
795
796
797
798
799
800
801







802
803
804
805
806
807
808
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833







+
+
+
+
+
+
+







	    winPtr2 = dispPtr->grabWinPtr;
	}
	if (winPtr2 != winPtr) {
	    TkChangeEventWindow(eventPtr, winPtr2);
	    Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_HEAD);
	    return 0;
	}

        /*
         * Warp the mouse pointer with respect to window dispPtr->warpWindow
         * if such a window was set in HandleEventGenerate.
         */

        TkDoWarpWrtWin(dispPtr);
	return 1;
    }

    /*
     * Process ButtonPress and ButtonRelease events:
     * 1. Keep track of whether a button is down and what window it went down
     *    in.
867
868
869
870
871
872
873
874

875
876
877
878
879
880
881
892
893
894
895
896
897
898

899
900
901
902
903
904
905
906







-
+







		}
		dispPtr->buttonWinPtr = winPtr;
		return 1;
	    }
	} else {
	    if (eventPtr->xbutton.button != AnyButton &&
		    ((eventPtr->xbutton.state & ALL_BUTTONS)
		    == TkGetButtonMask(eventPtr->xbutton.button))) {
		    == Tk_GetButtonMask(eventPtr->xbutton.button))) {
		ReleaseButtonGrab(dispPtr);			/* Note 4. */
	    }
	}
	if (winPtr2 != winPtr) {
	    TkChangeEventWindow(eventPtr, winPtr2);
	    Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_HEAD);
	    return 0;						/* Note 3. */
1366
1367
1368
1369
1370
1371
1372
1373

1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1391
1392
1393
1394
1395
1396
1397

1398
1399
1400
1401
1402

1403
1404
1405
1406
1407
1408
1409







-
+




-







 *
 *----------------------------------------------------------------------
 */

static int
GrabWinEventProc(
    Tcl_Event *evPtr,		/* Event of type NewGrabWinEvent. */
    int flags)			/* Flags argument to Tcl_DoOneEvent: indicates
    TCL_UNUSED(int))			/* Flags argument to Tcl_DoOneEvent: indicates
				 * what kinds of events are being processed
				 * right now. */
{
    NewGrabWinEvent *grabEvPtr = (NewGrabWinEvent *) evPtr;
    (void)flags;

    grabEvPtr->dispPtr->grabWinPtr = (TkWindow *) Tk_IdToWindow(
	    grabEvPtr->dispPtr->display, grabEvPtr->grabWindow);
    return 1;
}

/*

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

62
63
64
65
66
67
68
69

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

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103


104
105
106
107
108

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

128
129
130
131
132
133

134
135
136
137

138
139
140
141
142

143
144

145
146
147

148
149
150
151

152
153
154
155
156
157
158
159
160

161
162
163

164
165
166
167
168




169
170
171

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

189
190
191
192
193

194
195
196
197
198
199
200
201
202

203
204

205
206
207
208
209
210
211
62
63
64
65
66
67
68

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

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101


102
103
104
105
106
107

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

127
128
129
130
131
132

133
134
135
136

137
138
139
140
141

142
143

144
145
146

147
148
149
150

151
152
153
154
155
156
157
158
159

160
161
162

163
164




165
166
167
168
169
170

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

188
189
190
191
192

193
194
195
196
197
198
199
200
201

202
203

204
205
206
207
208
209
210
211







-
+













-
+


















-
-
+
+




-
+


















-
+





-
+



-
+




-
+

-
+


-
+



-
+








-
+


-
+

-
-
-
-
+
+
+
+


-
+
















-
+




-
+








-
+

-
+







/*
 * Default value for 'grid anchor'.
 */

#define GRID_DEFAULT_ANCHOR TK_ANCHOR_NW

/*
 * Structure to hold information for grid masters. A slot is either a row or
 * Structure to hold information for grid containers. A slot is either a row or
 * column.
 */

typedef struct SlotInfo {
    int minSize;		/* The minimum size of this slot (in pixels).
				 * It is set via the rowconfigure or
				 * columnconfigure commands. */
    int weight;			/* The resize weight of this slot. (0) means
				 * this slot doesn't resize. Extra space in
				 * the layout is given distributed among slots
				 * inproportion to their weights. */
    int pad;			/* Extra padding, in pixels, required for this
				 * slot. This amount is "added" to the largest
				 * slave in the slot. */
				 * content in the slot. */
    Tk_Uid uniform;		/* Value of -uniform option. It is used to
				 * group slots that should have the same
				 * size. */
    int offset;			/* This is a cached value used for
				 * introspection. It is the pixel offset of
				 * the right or bottom edge of this slot from
				 * the beginning of the layout. */
    int temp;			/* This is a temporary value used for
				 * calculating adjusted weights when shrinking
				 * the layout below its nominal size. */
} SlotInfo;

/*
 * Structure to hold information during layout calculations. There is one of
 * these for each slot, an array for each of the rows or columns.
 */

typedef struct GridLayout {
    struct Gridder *binNextPtr;	/* The next slave window in this bin. Each bin
    				 * contains a list of all slaves whose spans
    struct Gridder *binNextPtr;	/* The next content window in this bin. Each bin
    				 * contains a list of all content whose spans
    				 * are >1 and whose right edges fall in this
    				 * slot. */
    int minSize;		/* Minimum size needed for this slot, in
    				 * pixels. This is the space required to hold
    				 * any slaves contained entirely in this slot,
    				 * any content contained entirely in this slot,
    				 * adjusted for any slot constrants, such as
    				 * size or padding. */
    int pad;			/* Padding needed for this slot */
    int weight;			/* Slot weight, controls resizing. */
    Tk_Uid uniform;		/* Value of -uniform option. It is used to
				 * group slots that should have the same
				 * size. */
    int minOffset;		/* The minimum offset, in pixels, from the
    				 * beginning of the layout to the bottom/right
    				 * edge of the slot calculated from top/left
    				 * to bottom/right. */
    int maxOffset;		/* The maximum offset, in pixels, from the
    				 * beginning of the layout to the bottom/right
    				 * edge of the slot calculated from
    				 * bottom/right to top/left. */
} GridLayout;

/*
 * Keep one of these for each geometry master.
 * Keep one of these for each geometry container.
 */

typedef struct {
    SlotInfo *columnPtr;	/* Pointer to array of column constraints. */
    SlotInfo *rowPtr;		/* Pointer to array of row constraints. */
    int columnEnd;		/* The last column occupied by any slave. */
    int columnEnd;		/* The last column occupied by any content. */
    int columnMax;		/* The number of columns with constraints. */
    int columnSpace;		/* The number of slots currently allocated for
    				 * column constraints. */
    int rowEnd;			/* The last row occupied by any slave. */
    int rowEnd;			/* The last row occupied by any content. */
    int rowMax;			/* The number of rows with constraints. */
    int rowSpace;		/* The number of slots currently allocated for
    				 * row constraints. */
    int startX;			/* Pixel offset of this layout within its
    				 * master. */
    				 * container. */
    int startY;			/* Pixel offset of this layout within its
    				 * master. */
    				 * container. */
    Tk_Anchor anchor;		/* Value of anchor option: specifies where a
				 * grid without weight should be placed. */
} GridMaster;
} GridContainer;

/*
 * For each window that the grid cares about (either because the window is
 * managed by the grid or because the window has slaves that are managed by
 * managed by the grid or because the window has content that are managed by
 * the grid), there is a structure of the following type:
 */

typedef struct Gridder {
    Tk_Window tkwin;		/* Tk token for window. NULL means that the
				 * window has been deleted, but the gridder
				 * hasn't had a chance to clean up yet because
				 * the structure is still in use. */
    struct Gridder *masterPtr;	/* Master window within which this window is
    struct Gridder *containerPtr;	/* Container window within which this window is
				 * managed (NULL means this window isn't
				 * managed by the gridder). */
    struct Gridder *nextPtr;	/* Next window managed within same master.
    struct Gridder *nextPtr;	/* Next window managed within same container.
				 * List order doesn't matter. */
    struct Gridder *slavePtr;	/* First in list of slaves managed inside this
				 * window (NULL means no grid slaves). */
    GridMaster *masterDataPtr;	/* Additional data for geometry master. */
    Tcl_Obj *in;                /* Store master name when removed. */
    struct Gridder *contentPtr;	/* First in list of content managed inside this
				 * window (NULL means no grid content). */
    GridContainer *containerDataPtr;	/* Additional data for geometry container. */
    Tcl_Obj *in;                /* Store container name when removed. */
    int column, row;		/* Location in the grid (starting from
				 * zero). */
    int numCols, numRows;	/* Number of columns or rows this slave spans.
    int numCols, numRows;	/* Number of columns or rows this content spans.
				 * Should be at least 1. */
    int padX, padY;		/* Total additional pixels to leave around the
				 * window. Some is of this space is on each
				 * side. This is space *outside* the window:
				 * we'll allocate extra space in frame but
				 * won't enlarge window). */
    int padLeft, padTop;	/* The part of padX or padY to use on the left
				 * or top of the widget, respectively. By
				 * default, this is half of padX or padY. */
    int iPadX, iPadY;		/* Total extra pixels to allocate inside the
				 * window (half this amount will appear on
				 * each side). */
    int sticky;			/* which sides of its cavity this window
				 * sticks to. See below for definitions */
    int doubleBw;		/* Twice the window's last known border width.
				 * If this changes, the window must be
				 * re-arranged within its master. */
				 * re-arranged within its container. */
    int *abortPtr;		/* If non-NULL, it means that there is a
				 * nested call to ArrangeGrid already working
				 * on this window. *abortPtr may be set to 1
				 * to abort that nested call. This happens,
				 * for example, if tkwin or any of its slaves
				 * for example, if tkwin or any of its content
				 * is deleted. */
    int flags;			/* Miscellaneous flags; see below for
				 * definitions. */

    /*
     * These fields are used temporarily for layout calculations only.
     */

    struct Gridder *binNextPtr;	/* Link to next span>1 slave in this bin. */
    struct Gridder *binNextPtr;	/* Link to next span>1 content in this bin. */
    int size;			/* Nominal size (width or height) in pixels of
    				 * the slave. This includes the padding. */
    				 * the content. This includes the padding. */
} Gridder;

/*
 * Flag values for "sticky"ness. The 16 combinations subsume the packer's
 * notion of anchor and fill.
 *
 * STICK_NORTH			This window sticks to the top of its cavity.
231
232
233
234
235
236
237
238

239
240
241

242
243
244
245



246
247
248
249
250

251
252
253
254
255
256

257
258
259
260
261

262
263

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

238
239
240

241
242



243
244
245
246
247
248
249

250
251
252
253
254
255

256
257
258
259
260

261
262

263
264
265
266
267
268
269
270







-
+


-
+

-
-
-
+
+
+




-
+





-
+




-
+

-
+







    int minSize;
} UniformGroup;

/*
 * Flag values for Grid structures:
 *
 * REQUESTED_RELAYOUT		1 means a Tcl_DoWhenIdle request has already
 *				been made to re-arrange all the slaves of this
 *				been made to re-arrange all the content of this
 *				window.
 * DONT_PROPAGATE		1 means don't set this window's requested
 *				size. 0 means if this window is a master then
 *				size. 0 means if this window is a container then
 *				Tk will set its requested size to fit the
 *				needs of its slaves.
 * ALLOCED_MASTER               1 means that Grid has allocated itself as
 *                              geometry master for this window.
 *				needs of its content.
 * ALLOCED_CONTAINER		1 means that Grid has allocated itself as
 *				geometry container for this window.
 */

#define REQUESTED_RELAYOUT	1
#define DONT_PROPAGATE		2
#define ALLOCED_MASTER		4
#define ALLOCED_CONTAINER	4

/*
 * Prototypes for procedures used only in this file:
 */

static void		AdjustForSticky(Gridder *slavePtr, int *xPtr,
static void		AdjustForSticky(Gridder *contentPtr, int *xPtr,
			    int *yPtr, int *widthPtr, int *heightPtr);
static int		AdjustOffsets(int width, int elements,
			    SlotInfo *slotPtr);
static void		ArrangeGrid(ClientData clientData);
static int		CheckSlotData(Gridder *masterPtr, int slot,
static int		CheckSlotData(Gridder *containerPtr, int slot,
			    int slotType, int checkOnly);
static int		ConfigureSlaves(Tcl_Interp *interp, Tk_Window tkwin,
static int		ConfigureContent(Tcl_Interp *interp, Tk_Window tkwin,
			    int objc, Tcl_Obj *const objv[]);
static void		DestroyGrid(void *memPtr);
static Gridder *	GetGrid(Tk_Window tkwin);
static int		GridAnchorCommand(Tk_Window tkwin, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
static int		GridBboxCommand(Tk_Window tkwin, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
280
281
282
283
284
285
286
287

288
289
290
291

292
293
294

295
296
297
298
299
300

301
302

303
304
305
306
307
308
309
310
311

312
313
314
315
316
317
318
280
281
282
283
284
285
286

287
288
289
290

291
292
293

294
295
296
297
298
299

300
301

302
303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
318







-
+



-
+


-
+





-
+

-
+








-
+







			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		GridRowColumnConfigureCommand(Tk_Window tkwin,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		GridSizeCommand(Tk_Window tkwin, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
static int		GridSlavesCommand(Tk_Window tkwin, Tcl_Interp *interp,
static int		GridContentCommand(Tk_Window tkwin, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
static void		GridStructureProc(ClientData clientData,
			    XEvent *eventPtr);
static void		GridLostSlaveProc(ClientData clientData,
static void		GridLostContentProc(ClientData clientData,
			    Tk_Window tkwin);
static void		GridReqProc(ClientData clientData, Tk_Window tkwin);
static void		InitMasterData(Gridder *masterPtr);
static void		InitContainerData(Gridder *containerPtr);
static Tcl_Obj *	NewPairObj(Tcl_WideInt, Tcl_WideInt);
static Tcl_Obj *	NewQuadObj(Tcl_WideInt, Tcl_WideInt, Tcl_WideInt, Tcl_WideInt);
static int		ResolveConstraints(Gridder *gridPtr, int rowOrColumn,
			    int maxOffset);
static void		SetGridSize(Gridder *gridPtr);
static int		SetSlaveColumn(Tcl_Interp *interp, Gridder *slavePtr,
static int		SetContentColumn(Tcl_Interp *interp, Gridder *contentPtr,
			    int column, int numCols);
static int		SetSlaveRow(Tcl_Interp *interp, Gridder *slavePtr,
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 */
    GridLostSlaveProc,		/* lostSlaveProc */
    GridLostContentProc,		/* lostContentProc */
};

/*
 *----------------------------------------------------------------------
 *
 * Tk_GridCmd --
 *
334
335
336
337
338
339
340
341
342







343
344
345
346
347


348
349
350
351
352
353
354
355
356

357
358
359
360
361
362
363








364
365


366
367
368
369
370
371
372
373
374
375

376
377
378
379
380
381
382
383
384
385
386
387

388

389
390
391
392
393
394
395
396





397
398
399
400
401
402
403
334
335
336
337
338
339
340


341
342
343
344
345
346
347
348
349
350


351
352
353
354
355
356
357
358
359
360

361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376


377
378
379
380
381
382
383
384
385
386
387

388
389
390
391
392
393
394
395
396
397
398
399
400
401

402
403
404
405





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







-
-
+
+
+
+
+
+
+



-
-
+
+








-
+







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









-
+












+
-
+



-
-
-
-
-
+
+
+
+
+







    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    static const char *const optionStrings[] = {
	"anchor", "bbox", "columnconfigure", "configure",
	"forget", "info", "location", "propagate", "remove",
	"rowconfigure", "size",	"slaves", NULL
	"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_FORGET, GRID_INFO, GRID_LOCATION, GRID_PROPAGATE, GRID_REMOVE,
	GRID_ROWCONFIGURE, GRID_SIZE, GRID_SLAVES
	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 ConfigureSlaves(interp, tkwin, objc-1, objv+1);
	    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.
	 */

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	Tcl_GetIndexFromObjStruct(interp, objv[1], optionStringsNoDep,
		sizeof(char *), "option", 0, &index);
	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case GRID_ANCHOR:
	return GridAnchorCommand(tkwin, interp, objc, objv);
    case GRID_BBOX:
	return GridBboxCommand(tkwin, interp, objc, objv);
    case GRID_CONFIGURE:
	return ConfigureSlaves(interp, tkwin, objc-2, objv+2);
	return ConfigureContent(interp, tkwin, objc-2, objv+2);
    case GRID_FORGET:
    case GRID_REMOVE:
	return GridForgetRemoveCommand(tkwin, interp, objc, objv);
    case GRID_INFO:
	return GridInfoCommand(tkwin, interp, objc, objv);
    case GRID_LOCATION:
	return GridLocationCommand(tkwin, interp, objc, objv);
    case GRID_PROPAGATE:
	return GridPropagateCommand(tkwin, interp, objc, objv);
    case GRID_SIZE:
	return GridSizeCommand(tkwin, interp, objc, objv);
    case GRID_SLAVES:
    case GRID_CONTENT:
	return GridSlavesCommand(tkwin, interp, objc, objv);
	return GridContentCommand(tkwin, interp, objc, objv);

    /*
     * Sample argument combinations:
     *  grid columnconfigure <master> <index> -option
     *  grid columnconfigure <master> <index> -option value -option value
     *  grid rowconfigure <master> <index>
     *  grid rowconfigure <master> <index> -option
     *  grid rowconfigure <master> <index> -option value -option value.
     *  grid columnconfigure <container> <index> -option
     *  grid columnconfigure <container> <index> -option value -option value
     *  grid rowconfigure <container> <index>
     *  grid rowconfigure <container> <index> -option
     *  grid rowconfigure <container> <index> -option value -option value.
     */

    case GRID_COLUMNCONFIGURE:
    case GRID_ROWCONFIGURE:
	return GridRowColumnConfigureCommand(tkwin, interp, objc, objv);
    }

427
428
429
430
431
432
433
434
435
436



437
438
439
440
441
442
443
444

445
446
447

448
449
450

451
452
453
454
455
456
457
458


459
460
461
462
463
464
465
466
467
468
469
470


471
472
473
474



475
476
477
478
479
480
481
441
442
443
444
445
446
447



448
449
450
451
452
453
454
455
456
457

458
459
460

461
462
463

464
465
466
467
468
469
470


471
472
473
474
475
476
477
478
479
480
481
482


483
484
485



486
487
488
489
490
491
492
493
494
495







-
-
-
+
+
+







-
+


-
+


-
+






-
-
+
+










-
-
+
+

-
-
-
+
+
+







static int
GridAnchorCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window master;
    Gridder *masterPtr;
    GridMaster *gridPtr;
    Tk_Window container;
    Gridder *containerPtr;
    GridContainer *gridPtr;
    Tk_Anchor old;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?anchor?");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &master) != TCL_OK) {
    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }
    masterPtr = GetGrid(master);
    containerPtr = GetGrid(container);

    if (objc == 3) {
	gridPtr = masterPtr->masterDataPtr;
	gridPtr = containerPtr->containerDataPtr;
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		Tk_NameOfAnchor(gridPtr?gridPtr->anchor:GRID_DEFAULT_ANCHOR),
		-1));
	return TCL_OK;
    }

    InitMasterData(masterPtr);
    gridPtr = masterPtr->masterDataPtr;
    InitContainerData(containerPtr);
    gridPtr = containerPtr->containerDataPtr;
    old = gridPtr->anchor;
    if (Tk_GetAnchorFromObj(interp, objv[3], &gridPtr->anchor) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Only request a relayout if the anchor changes.
     */

    if (old != gridPtr->anchor) {
	if (masterPtr->abortPtr != NULL) {
	    *masterPtr->abortPtr = 1;
	if (containerPtr->abortPtr != NULL) {
	    *containerPtr->abortPtr = 1;
	}
	if (!(masterPtr->flags & REQUESTED_RELAYOUT)) {
	    masterPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, masterPtr);
	if (!(containerPtr->flags & REQUESTED_RELAYOUT)) {
	    containerPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, containerPtr);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
496
497
498
499
500
501
502
503
504
505



506
507
508
509
510
511
512
513

514
515
516
517

518
519
520

521
522
523
524
525
526
527
510
511
512
513
514
515
516



517
518
519
520
521
522
523
524
525
526

527
528
529
530

531
532
533

534
535
536
537
538
539
540
541







-
-
-
+
+
+







-
+



-
+


-
+







static int
GridBboxCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window master;
    Gridder *masterPtr;		/* master grid record */
    GridMaster *gridPtr;	/* pointer to grid data */
    Tk_Window container;
    Gridder *containerPtr;		/* container grid record */
    GridContainer *gridPtr;	/* pointer to grid data */
    int row, column;		/* origin for bounding box */
    int row2, column2;		/* end of bounding box */
    int endX, endY;		/* last column/row in the layout */
    int x=0, y=0;		/* starting pixels for this bounding box */
    int width, height;		/* size of the bounding box */

    if (objc!=3 && objc != 5 && objc != 7) {
	Tcl_WrongNumArgs(interp, 2, objv, "master ?column row ?column row??");
	Tcl_WrongNumArgs(interp, 2, objv, "window ?column row ?column row??");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &master) != TCL_OK) {
    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }
    masterPtr = GetGrid(master);
    containerPtr = GetGrid(container);

    if (objc >= 5) {
	if (Tcl_GetIntFromObj(interp, objv[3], &column) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (Tcl_GetIntFromObj(interp, objv[4], &row) != TCL_OK) {
	    return TCL_ERROR;
535
536
537
538
539
540
541
542

543
544
545
546
547
548

549
550
551
552
553
554
555
549
550
551
552
553
554
555

556
557
558
559
560
561

562
563
564
565
566
567
568
569







-
+





-
+







	    return TCL_ERROR;
	}
	if (Tcl_GetIntFromObj(interp, objv[6], &row2) != TCL_OK) {
	    return TCL_ERROR;
	}
    }

    gridPtr = masterPtr->masterDataPtr;
    gridPtr = containerPtr->containerDataPtr;
    if (gridPtr == NULL) {
	Tcl_SetObjResult(interp, NewQuadObj(0, 0, 0, 0));
	return TCL_OK;
    }

    SetGridSize(masterPtr);
    SetGridSize(containerPtr);
    endX = MAX(gridPtr->columnEnd, gridPtr->columnMax);
    endY = MAX(gridPtr->rowEnd, gridPtr->rowMax);

    if ((endX == 0) || (endY == 0)) {
	Tcl_SetObjResult(interp, NewQuadObj(0, 0, 0, 0));
	return TCL_OK;
    }
626
627
628
629
630
631
632
633
634


635
636
637
638
639
640

641
642
643
644
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
640
641
642
643
644
645
646


647
648
649
650
651
652
653

654
655
656
657


658
659
660
661
662
663
664













665
666
667
668
669
670
671
672
673
674
675
676
677
678



679
680
681
682


683
684
685
686


687
688
689
690



691
692
693
694




695
696
697
698
699
700




701
702
703
704
705


706
707
708
709
710
711
712
713
714







-
-
+
+





-
+



-
-
+
+





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

-
-
-
+
+
+

-
-
+
+


-
-
+
+


-
-
-
+
+
+

-
-
-
-
+
+
+
+


-
-
-
-
+
+
+
+

-
-
+
+







static int
GridForgetRemoveCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window slave;
    Gridder *slavePtr;
    Tk_Window content;
    Gridder *contentPtr;
    int i;
    const char *string = Tcl_GetString(objv[1]);
    char c = string[0];

    for (i = 2; i < objc; i++) {
	if (TkGetWindowFromObj(interp, tkwin, objv[i], &slave) != TCL_OK) {
	if (TkGetWindowFromObj(interp, tkwin, objv[i], &content) != TCL_OK) {
	    return TCL_ERROR;
	}

	slavePtr = GetGrid(slave);
	if (slavePtr->masterPtr != NULL) {
	contentPtr = GetGrid(content);
	if (contentPtr->containerPtr != NULL) {
	    /*
	     * For "forget", reset all the settings to their defaults
	     */

	    if (c == 'f') {
		slavePtr->column = -1;
		slavePtr->row = -1;
		slavePtr->numCols = 1;
		slavePtr->numRows = 1;
		slavePtr->padX = 0;
		slavePtr->padY = 0;
		slavePtr->padLeft = 0;
		slavePtr->padTop = 0;
		slavePtr->iPadX = 0;
		slavePtr->iPadY = 0;
		if (slavePtr->in != NULL) {
		    Tcl_DecrRefCount(slavePtr->in);
		    slavePtr->in = NULL;
		contentPtr->column = -1;
		contentPtr->row = -1;
		contentPtr->numCols = 1;
		contentPtr->numRows = 1;
		contentPtr->padX = 0;
		contentPtr->padY = 0;
		contentPtr->padLeft = 0;
		contentPtr->padTop = 0;
		contentPtr->iPadX = 0;
		contentPtr->iPadY = 0;
		if (contentPtr->in != NULL) {
		    Tcl_DecrRefCount(contentPtr->in);
		    contentPtr->in = NULL;
		}
		slavePtr->doubleBw = 2*Tk_Changes(tkwin)->border_width;
		if (slavePtr->flags & REQUESTED_RELAYOUT) {
		    Tcl_CancelIdleCall(ArrangeGrid, slavePtr);
		contentPtr->doubleBw = 2*Tk_Changes(tkwin)->border_width;
		if (contentPtr->flags & REQUESTED_RELAYOUT) {
		    Tcl_CancelIdleCall(ArrangeGrid, contentPtr);
		}
		slavePtr->flags = 0;
		slavePtr->sticky = 0;
		contentPtr->flags = 0;
		contentPtr->sticky = 0;
	    } else {
		/*
		 * When removing, store name of master to be able to
		 * restore it later, even if the master is recreated.
		 * When removing, store name of container to be able to
		 * restore it later, even if the container is recreated.
		 */

		if (slavePtr->in != NULL) {
		    Tcl_DecrRefCount(slavePtr->in);
		    slavePtr->in = NULL;
		if (contentPtr->in != NULL) {
		    Tcl_DecrRefCount(contentPtr->in);
		    contentPtr->in = NULL;
		}
		if (slavePtr->masterPtr != NULL) {
		    slavePtr->in = Tcl_NewStringObj(
			    Tk_PathName(slavePtr->masterPtr->tkwin), -1);
		    Tcl_IncrRefCount(slavePtr->in);
		if (contentPtr->containerPtr != NULL) {
		    contentPtr->in = Tcl_NewStringObj(
			    Tk_PathName(contentPtr->containerPtr->tkwin), -1);
		    Tcl_IncrRefCount(contentPtr->in);
		}
	    }
	    Tk_ManageGeometry(slave, NULL, NULL);
	    if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) {
		Tk_UnmaintainGeometry(slavePtr->tkwin,
			slavePtr->masterPtr->tkwin);
	    Tk_ManageGeometry(content, NULL, NULL);
	    if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
		Tk_UnmaintainGeometry(contentPtr->tkwin,
			contentPtr->containerPtr->tkwin);
	    }
	    Unlink(slavePtr);
	    Tk_UnmapWindow(slavePtr->tkwin);
	    Unlink(contentPtr);
	    Tk_UnmapWindow(contentPtr->tkwin);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
716
717
718
719
720
721
722
723
724


725
726
727
728
729
730
731

732
733
734
735


736
737
738
739
740
741
742

743
744

745
746

747
748

749
750
751
752
753
754





755
756

757
758
759
760
761
762
763
730
731
732
733
734
735
736


737
738
739
740
741
742
743
744

745
746
747


748
749
750
751
752
753
754
755

756
757

758
759

760
761

762
763





764
765
766
767
768
769

770
771
772
773
774
775
776
777







-
-
+
+






-
+


-
-
+
+






-
+

-
+

-
+

-
+

-
-
-
-
-
+
+
+
+
+

-
+







static int
GridInfoCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Gridder *slavePtr;
    Tk_Window slave;
    Gridder *contentPtr;
    Tk_Window content;
    Tcl_Obj *infoObj;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (TkGetWindowFromObj(interp, tkwin, objv[2], &slave) != TCL_OK) {
    if (TkGetWindowFromObj(interp, tkwin, objv[2], &content) != TCL_OK) {
	return TCL_ERROR;
    }
    slavePtr = GetGrid(slave);
    if (slavePtr->masterPtr == NULL) {
    contentPtr = GetGrid(content);
    if (contentPtr->containerPtr == NULL) {
	Tcl_ResetResult(interp);
	return TCL_OK;
    }

    infoObj = Tcl_NewObj();
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-in", -1),
	    TkNewWindowObj(slavePtr->masterPtr->tkwin));
	    Tk_NewWindowObj(contentPtr->containerPtr->tkwin));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-column", -1),
	    Tcl_NewWideIntObj(slavePtr->column));
	    Tcl_NewWideIntObj(contentPtr->column));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-row", -1),
	    Tcl_NewWideIntObj(slavePtr->row));
	    Tcl_NewWideIntObj(contentPtr->row));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-columnspan", -1),
	    Tcl_NewWideIntObj(slavePtr->numCols));
	    Tcl_NewWideIntObj(contentPtr->numCols));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-rowspan", -1),
	    Tcl_NewWideIntObj(slavePtr->numRows));
    TkAppendPadAmount(infoObj, "-ipadx", slavePtr->iPadX/2, slavePtr->iPadX);
    TkAppendPadAmount(infoObj, "-ipady", slavePtr->iPadY/2, slavePtr->iPadY);
    TkAppendPadAmount(infoObj, "-padx", slavePtr->padLeft, slavePtr->padX);
    TkAppendPadAmount(infoObj, "-pady", slavePtr->padTop, slavePtr->padY);
	    Tcl_NewWideIntObj(contentPtr->numRows));
    TkAppendPadAmount(infoObj, "-ipadx", contentPtr->iPadX/2, contentPtr->iPadX);
    TkAppendPadAmount(infoObj, "-ipady", contentPtr->iPadY/2, contentPtr->iPadY);
    TkAppendPadAmount(infoObj, "-padx", contentPtr->padLeft, contentPtr->padX);
    TkAppendPadAmount(infoObj, "-pady", contentPtr->padTop, contentPtr->padY);
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-sticky", -1),
	    StickyToObj(slavePtr->sticky));
	    StickyToObj(contentPtr->sticky));
    Tcl_SetObjResult(interp, infoObj);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
778
779
780
781
782
783
784
785
786
787



788
789

790
791
792
793
794





795
796
797
798
799
800
801
802

803
804
805

806
807
808
809
810


811
812
813
814

815
816
817
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
792
793
794
795
796
797
798



799
800
801
802

803
804
805
806
807

808
809
810
811
812
813
814
815





816
817
818

819
820
821
822


823
824
825
826
827

828
829
830
831
832
833
834
835



836
837
838
839

840
841
842
843


844
845
846
847

848
849
850
851
852
853


854
855
856
857

858
859
860
861
862
863
864
865







-
-
-
+
+
+

-
+




-
+
+
+
+
+



-
-
-
-
-
+


-
+



-
-
+
+



-
+







-
-
-
+
+
+

-
+



-
-
+
+


-
+





-
-
+
+


-
+







static int
GridLocationCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window master;
    Gridder *masterPtr;		/* Master grid record. */
    GridMaster *gridPtr;	/* Pointer to grid data. */
    Tk_Window container;
    Gridder *containerPtr;		/* Container grid record. */
    GridContainer *gridPtr;	/* Pointer to grid data. */
    SlotInfo *slotPtr;
    int x, y;			/* Offset in pixels, from edge of master. */
    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, "master x y");
	Tcl_WrongNumArgs(interp, 2, objv, "window x y");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &master) != TCL_OK) {
	return TCL_ERROR;
    }

    if (Tk_GetPixelsFromObj(interp, master, objv[3], &x) != TCL_OK) {
    if (Tk_GetPixelsFromObj(interp, container, objv[3], &x) != TCL_OK) {
	return TCL_ERROR;
    }
    if (Tk_GetPixelsFromObj(interp, master, objv[4], &y) != TCL_OK) {
    if (Tk_GetPixelsFromObj(interp, container, objv[4], &y) != TCL_OK) {
	return TCL_ERROR;
    }

    masterPtr = GetGrid(master);
    if (masterPtr->masterDataPtr == NULL) {
    containerPtr = GetGrid(container);
    if (containerPtr->containerDataPtr == NULL) {
	Tcl_SetObjResult(interp, NewPairObj(-1, -1));
	return TCL_OK;
    }
    gridPtr = masterPtr->masterDataPtr;
    gridPtr = containerPtr->containerDataPtr;

    /*
     * Update any pending requests. This is not always the steady state value,
     * as more configure events could be in the pipeline, but its as close as
     * its easy to get.
     */

    while (masterPtr->flags & REQUESTED_RELAYOUT) {
	Tcl_CancelIdleCall(ArrangeGrid, masterPtr);
	ArrangeGrid(masterPtr);
    while (containerPtr->flags & REQUESTED_RELAYOUT) {
	Tcl_CancelIdleCall(ArrangeGrid, containerPtr);
	ArrangeGrid(containerPtr);
    }
    SetGridSize(masterPtr);
    SetGridSize(containerPtr);
    endX = MAX(gridPtr->columnEnd, gridPtr->columnMax);
    endY = MAX(gridPtr->rowEnd, gridPtr->rowMax);

    slotPtr = masterPtr->masterDataPtr->columnPtr;
    if (x < masterPtr->masterDataPtr->startX) {
    slotPtr = containerPtr->containerDataPtr->columnPtr;
    if (x < containerPtr->containerDataPtr->startX) {
	i = -1;
    } else {
	x -= masterPtr->masterDataPtr->startX;
	x -= containerPtr->containerDataPtr->startX;
	for (i = 0; slotPtr[i].offset < x && i < endX; i++) {
	    /* null body */
	}
    }

    slotPtr = masterPtr->masterDataPtr->rowPtr;
    if (y < masterPtr->masterDataPtr->startY) {
    slotPtr = containerPtr->containerDataPtr->rowPtr;
    if (y < containerPtr->containerDataPtr->startY) {
	j = -1;
    } else {
	y -= masterPtr->masterDataPtr->startY;
	y -= containerPtr->containerDataPtr->startY;
	for (j = 0; slotPtr[j].offset < y && j < endY; j++) {
	    /* null body */
	}
    }

    Tcl_SetObjResult(interp, NewPairObj(i, j));
    return TCL_OK;
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
885
886
887
888
889
890
891


892
893
894
895
896
897
898
899
900

901
902
903

904
905
906

907
908
909
910
911
912
913
914
915
916
917

918
919
920
921

922
923
924


925
926
927
928

929
930

931
932



933
934
935
936

937
938
939
940


941
942
943
944


945
946
947



948
949
950
951
952
953
954
955
956
957







-
-
+
+







-
+


-
+


-
+










-
+



-
+


-
-
+
+


-
+

-
+

-
-
-
+
+
+

-
+



-
-
+
+


-
-
+
+

-
-
-
+
+
+







static int
GridPropagateCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window master;
    Gridder *masterPtr;
    Tk_Window container;
    Gridder *containerPtr;
    int propagate, old;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &master) != TCL_OK) {
    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }
    masterPtr = GetGrid(master);
    containerPtr = GetGrid(container);
    if (objc == 3) {
	Tcl_SetObjResult(interp,
		Tcl_NewBooleanObj(!(masterPtr->flags & DONT_PROPAGATE)));
		Tcl_NewBooleanObj(!(containerPtr->flags & DONT_PROPAGATE)));
	return TCL_OK;
    }
    if (Tcl_GetBooleanFromObj(interp, objv[3], &propagate) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Only request a relayout if the propagation bit changes.
     */

    old = !(masterPtr->flags & DONT_PROPAGATE);
    old = !(containerPtr->flags & DONT_PROPAGATE);
    if (propagate != old) {
	if (propagate) {
	    /*
	     * If we have slaves, we need to register as geometry master.
	     * If we have content, we need to register as geometry container.
	     */

	    if (masterPtr->slavePtr != NULL) {
		if (TkSetGeometryMaster(interp, master, "grid")	!= TCL_OK) {
	    if (containerPtr->contentPtr != NULL) {
		if (TkSetGeometryContainer(interp, container, "grid")	!= TCL_OK) {
		    return TCL_ERROR;
		}
		masterPtr->flags |= ALLOCED_MASTER;
		containerPtr->flags |= ALLOCED_CONTAINER;
	    }
	    masterPtr->flags &= ~DONT_PROPAGATE;
	    containerPtr->flags &= ~DONT_PROPAGATE;
	} else {
	    if (masterPtr->flags & ALLOCED_MASTER) {
		TkFreeGeometryMaster(master, "grid");
		masterPtr->flags &= ~ALLOCED_MASTER;
	    if (containerPtr->flags & ALLOCED_CONTAINER) {
		TkFreeGeometryContainer(container, "grid");
		containerPtr->flags &= ~ALLOCED_CONTAINER;
	    }
	    masterPtr->flags |= DONT_PROPAGATE;
	    containerPtr->flags |= DONT_PROPAGATE;
	}

	/*
	 * Re-arrange the master to allow new geometry information to
	 * propagate upwards to the master's master.
	 * Re-arrange the container to allow new geometry information to
	 * propagate upwards to the container's container.
	 */

	if (masterPtr->abortPtr != NULL) {
	    *masterPtr->abortPtr = 1;
	if (containerPtr->abortPtr != NULL) {
	    *containerPtr->abortPtr = 1;
	}
	if (!(masterPtr->flags & REQUESTED_RELAYOUT)) {
	    masterPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, masterPtr);
	if (!(containerPtr->flags & REQUESTED_RELAYOUT)) {
	    containerPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, containerPtr);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
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
973
974
975
976
977
978
979


980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000

1001
1002
1003
1004

1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025

1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045

1046
1047
1048


1049
1050
1051
1052
1053
1054
1055
1056
1057







-
-
+
+



















-
+



-
+




















-
+



















-
+


-
-
+
+







static int
GridRowColumnConfigureCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window master, slave;
    Gridder *masterPtr, *slavePtr;
    Tk_Window container, content;
    Gridder *containerPtr, *contentPtr;
    SlotInfo *slotPtr = NULL;
    int slot;			/* the column or row number */
    int slotType;		/* COLUMN or ROW */
    int size;			/* the configuration value */
    int lObjc;			/* Number of items in index list */
    Tcl_Obj **lObjv;		/* array of indices */
    int ok;			/* temporary TCL result code */
    int i, j, first, last;
    const char *string;
    static const char *const optionStrings[] = {
	"-minsize", "-pad", "-uniform", "-weight", NULL
    };
    enum options {
	ROWCOL_MINSIZE, ROWCOL_PAD, ROWCOL_UNIFORM, ROWCOL_WEIGHT
    };
    int index;
    Tcl_Obj *listCopy;

    if (((objc % 2 != 0) && (objc > 6)) || (objc < 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "master index ?-option value ...?");
	Tcl_WrongNumArgs(interp, 2, objv, "window index ?-option value ...?");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &master) != TCL_OK) {
    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }

    listCopy = Tcl_DuplicateObj(objv[3]);
    Tcl_IncrRefCount(listCopy);
    if (Tcl_ListObjGetElements(interp, listCopy, &lObjc, &lObjv) != TCL_OK) {
	Tcl_DecrRefCount(listCopy);
	return TCL_ERROR;
    }

    string = Tcl_GetString(objv[1]);
    slotType = (*string == 'c') ? COLUMN : ROW;
    if (lObjc == 0) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("no %s indices specified",
		(slotType == COLUMN) ? "column" : "row"));
	Tcl_SetErrorCode(interp, "TK", "GRID", "NO_INDEX", NULL);
	Tcl_DecrRefCount(listCopy);
	return TCL_ERROR;
    }

    masterPtr = GetGrid(master);
    containerPtr = GetGrid(container);
    first = 0;
    last = 0;

    if ((objc == 4) || (objc == 5)) {
	if (lObjc != 1) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "must specify a single element on retrieval", -1));
	    Tcl_SetErrorCode(interp, "TK", "GRID", "USAGE", NULL);
	    Tcl_DecrRefCount(listCopy);
	    return TCL_ERROR;
	}
	if (Tcl_GetIntFromObj(interp, lObjv[0], &slot) != TCL_OK) {
	    Tcl_AppendResult(interp,
		    " (when retrieving options only integer indices are "
		    "allowed)", NULL);
	    Tcl_SetErrorCode(interp, "TK", "GRID", "INDEX_FORMAT", NULL);
	    Tcl_DecrRefCount(listCopy);
	    return TCL_ERROR;
	}
	ok = CheckSlotData(masterPtr, slot, slotType, /* checkOnly */ 1);
	ok = CheckSlotData(containerPtr, slot, slotType, /* checkOnly */ 1);
	if (ok == TCL_OK) {
	    slotPtr = (slotType == COLUMN) ?
		    masterPtr->masterDataPtr->columnPtr :
		    masterPtr->masterDataPtr->rowPtr;
		    containerPtr->containerDataPtr->columnPtr :
		    containerPtr->containerDataPtr->rowPtr;
	}

	/*
	 * Return all of the options for this row or column. If the request is
	 * out of range, return all 0's.
	 */

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







-
+




-
+


-
+


-
+

-
-
+
+


-
-
+
+


-
+


-
-
+
+



-
+
















-
+

-
+

-
+



-
+










-
-
+
+













-
+







		    (ok == TCL_OK) ? slotPtr[slot].pad : 0));
	}
	Tcl_DecrRefCount(listCopy);
	return TCL_OK;
    }

    for (j = 0; j < lObjc; j++) {
	int allSlaves = 0;
	int allContent = 0;

	if (Tcl_GetIntFromObj(NULL, lObjv[j], &slot) == TCL_OK) {
	    first = slot;
	    last = slot;
	    slavePtr = NULL;
	    contentPtr = NULL;
	} else if (strcmp(Tcl_GetString(lObjv[j]), "all") == 0) {
	    /*
	     * Make sure master is initialised.
	     * Make sure container is initialised.
	     */

	    InitMasterData(masterPtr);
	    InitContainerData(containerPtr);

	    slavePtr = masterPtr->slavePtr;
	    if (slavePtr == NULL) {
	    contentPtr = containerPtr->contentPtr;
	    if (contentPtr == NULL) {
		continue;
	    }
	    allSlaves = 1;
	} else if (TkGetWindowFromObj(NULL, tkwin, lObjv[j], &slave)
	    allContent = 1;
	} else if (TkGetWindowFromObj(NULL, tkwin, lObjv[j], &content)
		== TCL_OK) {
	    /*
	     * Is it gridded in this master?
	     * Is it gridded in this container?
	     */

	    slavePtr = GetGrid(slave);
	    if (slavePtr->masterPtr != masterPtr) {
	    contentPtr = GetGrid(content);
	    if (contentPtr->containerPtr != containerPtr) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"the window \"%s\" is not managed by \"%s\"",
			Tcl_GetString(lObjv[j]), Tcl_GetString(objv[2])));
		Tcl_SetErrorCode(interp, "TK", "GRID", "NOT_MASTER", NULL);
		Tcl_SetErrorCode(interp, "TK", "GRID", "NOT_MANAGED", NULL);
		Tcl_DecrRefCount(listCopy);
		return TCL_ERROR;
	    }
	} else {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "illegal index \"%s\"", Tcl_GetString(lObjv[j])));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID_INDEX", NULL);
	    Tcl_DecrRefCount(listCopy);
	    return TCL_ERROR;
	}

	/*
	 * The outer loop is only to handle "all".
	 */

	do {
	    if (slavePtr != NULL) {
	    if (contentPtr != NULL) {
		first = (slotType == COLUMN) ?
			slavePtr->column : slavePtr->row;
			contentPtr->column : contentPtr->row;
		last = first - 1 + ((slotType == COLUMN) ?
			slavePtr->numCols : slavePtr->numRows);
			contentPtr->numCols : contentPtr->numRows);
	    }

	    for (slot = first; slot <= last; slot++) {
		ok = CheckSlotData(masterPtr, slot, slotType, /*checkOnly*/ 0);
		ok = CheckSlotData(containerPtr, slot, slotType, /*checkOnly*/ 0);
		if (ok != TCL_OK) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "\"%s\" is out of range",
			    Tcl_GetString(lObjv[j])));
		    Tcl_SetErrorCode(interp, "TK", "GRID", "INDEX_RANGE",
			    NULL);
		    Tcl_DecrRefCount(listCopy);
		    return TCL_ERROR;
		}
		slotPtr = (slotType == COLUMN) ?
			masterPtr->masterDataPtr->columnPtr :
			masterPtr->masterDataPtr->rowPtr;
			containerPtr->containerDataPtr->columnPtr :
			containerPtr->containerDataPtr->rowPtr;

		/*
		 * Loop through each option value pair, setting the values as
		 * required.
		 */

		for (i = 4; i < objc; i += 2) {
		    if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings,
			    sizeof(char *), "option", 0, &index) != TCL_OK) {
			Tcl_DecrRefCount(listCopy);
			return TCL_ERROR;
		    }
		    if (index == ROWCOL_MINSIZE) {
			if (Tk_GetPixelsFromObj(interp, master, objv[i+1],
			if (Tk_GetPixelsFromObj(interp, container, objv[i+1],
				&size) != TCL_OK) {
			    Tcl_DecrRefCount(listCopy);
			    return TCL_ERROR;
			} else {
			    slotPtr[slot].minSize = size;
			}
		    } else if (index == ROWCOL_WEIGHT) {
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
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







-
+












-
-
+
+

-
+










-
+






-
+

-
+






-
+



-
-
+
+

-
-
-
+
+
+







			slotPtr[slot].uniform =
				Tk_GetUid(Tcl_GetString(objv[i+1]));
			if (slotPtr[slot].uniform != NULL &&
				slotPtr[slot].uniform[0] == 0) {
			    slotPtr[slot].uniform = NULL;
			}
		    } else if (index == ROWCOL_PAD) {
			if (Tk_GetPixelsFromObj(interp, master, objv[i+1],
			if (Tk_GetPixelsFromObj(interp, container, objv[i+1],
				&size) != TCL_OK) {
			    Tcl_DecrRefCount(listCopy);
			    return TCL_ERROR;
			} else if (size < 0) {
			    Tcl_DecrRefCount(listCopy);
			    goto negativeIndex;
			} else {
			    slotPtr[slot].pad = size;
			}
		    }
		}
	    }
	    if (slavePtr != NULL) {
		slavePtr = slavePtr->nextPtr;
	    if (contentPtr != NULL) {
		contentPtr = contentPtr->nextPtr;
	    }
	} while ((allSlaves == 1) && (slavePtr != NULL));
	} while ((allContent == 1) && (contentPtr != NULL));
    }
    Tcl_DecrRefCount(listCopy);

    /*
     * We changed a property, re-arrange the table, and check for constraint
     * shrinkage. A null slotPtr will occur for 'all' checks.
     */

    if (slotPtr != NULL) {
	if (slotType == ROW) {
	    int last = masterPtr->masterDataPtr->rowMax - 1;
	    last = containerPtr->containerDataPtr->rowMax - 1;

	    while ((last >= 0) && (slotPtr[last].weight == 0)
		    && (slotPtr[last].pad == 0) && (slotPtr[last].minSize == 0)
		    && (slotPtr[last].uniform == NULL)) {
		last--;
	    }
	    masterPtr->masterDataPtr->rowMax = last+1;
	    containerPtr->containerDataPtr->rowMax = last+1;
	} else {
	    int last = masterPtr->masterDataPtr->columnMax - 1;
	    last = containerPtr->containerDataPtr->columnMax - 1;

	    while ((last >= 0) && (slotPtr[last].weight == 0)
		    && (slotPtr[last].pad == 0) && (slotPtr[last].minSize == 0)
		    && (slotPtr[last].uniform == NULL)) {
		last--;
	    }
	    masterPtr->masterDataPtr->columnMax = last + 1;
	    containerPtr->containerDataPtr->columnMax = last + 1;
	}
    }

    if (masterPtr->abortPtr != NULL) {
	*masterPtr->abortPtr = 1;
    if (containerPtr->abortPtr != NULL) {
	*containerPtr->abortPtr = 1;
    }
    if (!(masterPtr->flags & REQUESTED_RELAYOUT)) {
	masterPtr->flags |= REQUESTED_RELAYOUT;
	Tcl_DoWhenIdle(ArrangeGrid, masterPtr);
    if (!(containerPtr->flags & REQUESTED_RELAYOUT)) {
	containerPtr->flags |= REQUESTED_RELAYOUT;
	Tcl_DoWhenIdle(ArrangeGrid, containerPtr);
    }
    return TCL_OK;

  negativeIndex:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "invalid arg \"%s\": should be non-negative",
	    Tcl_GetString(objv[i])));
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
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







-
-
-
+
+
+






-
+


-
+

-
-
-
+
+
+












-
+

-
+






-
-
+
+





-
+





-
-
-
+
+
+





-
+







static int
GridSizeCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window master;
    Gridder *masterPtr;
    GridMaster *gridPtr;	/* pointer to grid data */
    Tk_Window container;
    Gridder *containerPtr;
    GridContainer *gridPtr;	/* pointer to grid data */

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &master) != TCL_OK) {
    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }
    masterPtr = GetGrid(master);
    containerPtr = GetGrid(container);

    if (masterPtr->masterDataPtr != NULL) {
	SetGridSize(masterPtr);
	gridPtr = masterPtr->masterDataPtr;
    if (containerPtr->containerDataPtr != NULL) {
	SetGridSize(containerPtr);
	gridPtr = containerPtr->containerDataPtr;
	Tcl_SetObjResult(interp, NewPairObj(
		MAX(gridPtr->columnEnd, gridPtr->columnMax),
		MAX(gridPtr->rowEnd, gridPtr->rowMax)));
    } else {
	Tcl_SetObjResult(interp, NewPairObj(0, 0));
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GridSlavesCommand --
 * GridContentCommand --
 *
 *	Implementation of the [grid slaves] subcommand. See the user
 *	Implementation of the [grid content] subcommand. See the user
 *	documentation for details on what it does.
 *
 * Results:
 *	Standard Tcl result.
 *
 * Side effects:
 *	Places a list of slaves of the specified window in the interpreter's
 *	result field.
 *	Places a list of content windows of the specified window in the
 *	interpreter's result field.
 *
 *----------------------------------------------------------------------
 */

static int
GridSlavesCommand(
GridContentCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window master;
    Gridder *masterPtr;		/* master grid record */
    Gridder *slavePtr;
    Tk_Window container;
    Gridder *containerPtr;		/* container grid record */
    Gridder *contentPtr;
    int i, value, index;
    int row = -1, column = -1;
    static const char *const optionStrings[] = {
	"-column", "-row", NULL
    };
    enum options { SLAVES_COLUMN, SLAVES_ROW };
    enum options { CONTENT_COLUMN, CONTENT_ROW };
    Tcl_Obj *res;

    if ((objc < 3) || ((objc % 2) == 0)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?-option value ...?");
	return TCL_ERROR;
    }

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







-
+






-
+


-
+


-
-
-
-
+
+
+
+


-
-
+
+


-
+







	}
	if (value < 0) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "%d is an invalid value: should NOT be < 0", value));
	    Tcl_SetErrorCode(interp, "TK", "GRID", "NEG_INDEX", NULL);
	    return TCL_ERROR;
	}
	if (index == SLAVES_COLUMN) {
	if (index == CONTENT_COLUMN) {
	    column = value;
	} else {
	    row = value;
	}
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &master) != TCL_OK) {
    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }
    masterPtr = GetGrid(master);
    containerPtr = GetGrid(container);

    res = Tcl_NewListObj(0, NULL);
    for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
	    slavePtr = slavePtr->nextPtr) {
	if ((column >= 0) && (slavePtr->column > column
		|| slavePtr->column+slavePtr->numCols-1 < column)) {
    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) && (slavePtr->row > row ||
		slavePtr->row+slavePtr->numRows-1 < row)) {
	if ((row >= 0) && (contentPtr->row > row ||
		contentPtr->row+contentPtr->numRows-1 < row)) {
	    continue;
	}
	Tcl_ListObjAppendElement(interp,res, TkNewWindowObj(slavePtr->tkwin));
	Tcl_ListObjAppendElement(interp,res, Tk_NewWindowObj(contentPtr->tkwin));
    }
    Tcl_SetObjResult(interp, res);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
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
1438
1439
1440
1441
1442
1443
1444

1445
1446
1447
1448

1449

1450
1451
1452
1453
1454
1455
1456
1457
1458
1459

1460
1461
1462

1463
1464
1465
1466
1467
1468

1469
1470
1471
1472
1473
1474


1475
1476
1477

1478
1479

1480

1481


1482
1483
1484


1485
1486
1487
1488
1489
1490
1491
1492
1493







-
+



-

-
+









-
+


-
+





-
+





-
-
+
+

-
+

-
+
-

-
-
+
+

-
-
+
+







 *----------------------------------------------------------------------
 */

static void
GridReqProc(
    ClientData clientData,	/* Grid's information about window that got
				 * new preferred geometry. */
    Tk_Window tkwin)		/* Other Tk-related information about the
    TCL_UNUSED(Tk_Window))		/* Other Tk-related information about the
				 * window. */
{
    Gridder *gridPtr = (Gridder *)clientData;
    (void)tkwin;

    gridPtr = gridPtr->masterPtr;
    gridPtr = gridPtr->containerPtr;
    if (gridPtr && !(gridPtr->flags & REQUESTED_RELAYOUT)) {
	gridPtr->flags |= REQUESTED_RELAYOUT;
	Tcl_DoWhenIdle(ArrangeGrid, gridPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * GridLostSlaveProc --
 * GridLostContentProc --
 *
 *	This procedure is invoked by Tk whenever some other geometry claims
 *	control over a slave that used to be managed by us.
 *	control over a content that used to be managed by us.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Forgets all grid-related information about the slave.
 *	Forgets all grid-related information about the content.
 *
 *----------------------------------------------------------------------
 */

static void
GridLostSlaveProc(
    ClientData clientData,	/* Grid structure for slave window that was
GridLostContentProc(
    ClientData clientData,	/* Grid structure for content window that was
				 * stolen away. */
    Tk_Window tkwin)		/* Tk's handle for the slave window. */
    TCL_UNUSED(Tk_Window))		/* Tk's handle for the content window. */
{
    Gridder *slavePtr = (Gridder *)clientData;
    Gridder *contentPtr = (Gridder *)clientData;
    (void)tkwin;

    if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) {
	Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin);
    if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
	Tk_UnmaintainGeometry(contentPtr->tkwin, contentPtr->containerPtr->tkwin);
    }
    Unlink(slavePtr);
    Tk_UnmapWindow(slavePtr->tkwin);
    Unlink(contentPtr);
    Tk_UnmapWindow(contentPtr->tkwin);
}

/*
 *----------------------------------------------------------------------
 *
 * AdjustOffsets --
 *
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
1653
1654
1655
1656
1657
1658
1659

1660
1661
1662
1663
1664

1665
1666
1667
1668
1669
1670
1671
1672
1673
1674

1675
1676
1677
1678
1679
1680



1681
1682
1683
1684




1685
1686
1687
1688
1689



1690
1691
1692
1693
1694



1695
1696
1697
1698
1699
1700
1701
1702
1703
1704







-
+




-
+









-
+





-
-
-
+
+
+

-
-
-
-
+
+
+
+

-
-
-
+
+
+


-
-
-
+
+
+







}

/*
 *----------------------------------------------------------------------
 *
 * AdjustForSticky --
 *
 *	This procedure adjusts the size of a slave in its cavity based on its
 *	This procedure adjusts the size of a content in its cavity based on its
 *	"sticky" flags.
 *
 * Results:
 *	The input x, y, width, and height are changed to represent the desired
 *	coordinates of the slave.
 *	coordinates of the content.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
AdjustForSticky(
    Gridder *slavePtr,	/* Slave window to arrange in its cavity. */
    Gridder *contentPtr,	/* Content window to arrange in its cavity. */
    int *xPtr,		/* Pixel location of the left edge of the cavity. */
    int *yPtr,		/* Pixel location of the top edge of the cavity. */
    int *widthPtr,	/* Width of the cavity (in pixels). */
    int *heightPtr)	/* Height of the cavity (in pixels). */
{
    int diffx = 0;	/* Cavity width - slave width. */
    int diffy = 0;	/* Cavity hight - slave height. */
    int sticky = slavePtr->sticky;
    int diffx = 0;	/* Cavity width - content width. */
    int diffy = 0;	/* Cavity hight - content height. */
    int sticky = contentPtr->sticky;

    *xPtr += slavePtr->padLeft;
    *widthPtr -= slavePtr->padX;
    *yPtr += slavePtr->padTop;
    *heightPtr -= slavePtr->padY;
    *xPtr += contentPtr->padLeft;
    *widthPtr -= contentPtr->padX;
    *yPtr += contentPtr->padTop;
    *heightPtr -= contentPtr->padY;

    if (*widthPtr > (Tk_ReqWidth(slavePtr->tkwin) + slavePtr->iPadX)) {
	diffx = *widthPtr - (Tk_ReqWidth(slavePtr->tkwin) + slavePtr->iPadX);
	*widthPtr = Tk_ReqWidth(slavePtr->tkwin) + slavePtr->iPadX;
    if (*widthPtr > (Tk_ReqWidth(contentPtr->tkwin) + contentPtr->iPadX)) {
	diffx = *widthPtr - (Tk_ReqWidth(contentPtr->tkwin) + contentPtr->iPadX);
	*widthPtr = Tk_ReqWidth(contentPtr->tkwin) + contentPtr->iPadX;
    }

    if (*heightPtr > (Tk_ReqHeight(slavePtr->tkwin) + slavePtr->iPadY)) {
	diffy = *heightPtr - (Tk_ReqHeight(slavePtr->tkwin) + slavePtr->iPadY);
	*heightPtr = Tk_ReqHeight(slavePtr->tkwin) + slavePtr->iPadY;
    if (*heightPtr > (Tk_ReqHeight(contentPtr->tkwin) + contentPtr->iPadY)) {
	diffy = *heightPtr - (Tk_ReqHeight(contentPtr->tkwin) + contentPtr->iPadY);
	*heightPtr = Tk_ReqHeight(contentPtr->tkwin) + contentPtr->iPadY;
    }

    if (sticky&STICK_EAST && sticky&STICK_WEST) {
	*widthPtr += diffx;
    }
    if (sticky&STICK_NORTH && sticky&STICK_SOUTH) {
	*heightPtr += diffy;
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
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







-
+






-
+


-
-
-
+
+
+





-
+


-
-
+
+



-
+



-
+









-
-
+
+

-
+

-
+





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

-
-
+
+

-
-
+
+


-
-
-
-
+
+
+
+

-
-
+
+

-
-
+
+




-
+





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




-
+



-
+



-
-
+
+

-
-
-
+
+




-
-
+
+




-
+



-
+



-
+

-
+

-
-
-
-
-
+
+
+
+
+






-
-
+
+


-
-
+
+



-
-
+
+

-
+




-
-
+
+

















-
+






-
+





-
+








-
+
















-
+










-
-
-
+
+
+

-
-
-
+
+
+







 *	time so that a series of grid requests can be merged into a single
 *	layout operation.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The slaves of masterPtr may get resized or moved.
 *	The content of containerPtr may get resized or moved.
 *
 *----------------------------------------------------------------------
 */

static void
ArrangeGrid(
    ClientData clientData)	/* Structure describing master whose slaves
    ClientData clientData)	/* Structure describing container whose content
				 * are to be re-layed out. */
{
    Gridder *masterPtr = (Gridder *)clientData;
    Gridder *slavePtr;
    GridMaster *slotPtr = masterPtr->masterDataPtr;
    Gridder *containerPtr = (Gridder *)clientData;
    Gridder *contentPtr;
    GridContainer *slotPtr = containerPtr->containerDataPtr;
    int abort;
    int width, height;		/* Requested size of layout, in pixels. */
    int realWidth, realHeight;	/* Actual size layout should take-up. */
    int usedX, usedY;

    masterPtr->flags &= ~REQUESTED_RELAYOUT;
    containerPtr->flags &= ~REQUESTED_RELAYOUT;

    /*
     * If the master has no slaves anymore, then don't change the master size.
     * Otherwise there is no way to "relinquish" control over the master
     * If the container has no content anymore, then don't change the container size.
     * Otherwise there is no way to "relinquish" control over the container
     * so another geometry manager can take over.
     */

    if (masterPtr->slavePtr == NULL) {
    if (containerPtr->contentPtr == NULL) {
	return;
    }

    if (masterPtr->masterDataPtr == NULL) {
    if (containerPtr->containerDataPtr == NULL) {
	return;
    }

    /*
     * Abort any nested call to ArrangeGrid for this window, since we'll do
     * everything necessary here, and set up so this call can be aborted if
     * necessary.
     */

    if (masterPtr->abortPtr != NULL) {
	*masterPtr->abortPtr = 1;
    if (containerPtr->abortPtr != NULL) {
	*containerPtr->abortPtr = 1;
    }
    masterPtr->abortPtr = &abort;
    containerPtr->abortPtr = &abort;
    abort = 0;
    Tcl_Preserve(masterPtr);
    Tcl_Preserve(containerPtr);

    /*
     * Call the constraint engine to fill in the row and column offsets.
     */

    SetGridSize(masterPtr);
    width = ResolveConstraints(masterPtr, COLUMN, 0);
    height = ResolveConstraints(masterPtr, ROW, 0);
    width += Tk_InternalBorderLeft(masterPtr->tkwin) +
	    Tk_InternalBorderRight(masterPtr->tkwin);
    height += Tk_InternalBorderTop(masterPtr->tkwin) +
	    Tk_InternalBorderBottom(masterPtr->tkwin);
    SetGridSize(containerPtr);
    width = ResolveConstraints(containerPtr, COLUMN, 0);
    height = ResolveConstraints(containerPtr, ROW, 0);
    width += Tk_InternalBorderLeft(containerPtr->tkwin) +
	    Tk_InternalBorderRight(containerPtr->tkwin);
    height += Tk_InternalBorderTop(containerPtr->tkwin) +
	    Tk_InternalBorderBottom(containerPtr->tkwin);

    if (width < Tk_MinReqWidth(masterPtr->tkwin)) {
	width = Tk_MinReqWidth(masterPtr->tkwin);
    if (width < Tk_MinReqWidth(containerPtr->tkwin)) {
	width = Tk_MinReqWidth(containerPtr->tkwin);
    }
    if (height < Tk_MinReqHeight(masterPtr->tkwin)) {
	height = Tk_MinReqHeight(masterPtr->tkwin);
    if (height < Tk_MinReqHeight(containerPtr->tkwin)) {
	height = Tk_MinReqHeight(containerPtr->tkwin);
    }

    if (((width != Tk_ReqWidth(masterPtr->tkwin))
	    || (height != Tk_ReqHeight(masterPtr->tkwin)))
	    && !(masterPtr->flags & DONT_PROPAGATE)) {
	Tk_GeometryRequest(masterPtr->tkwin, width, height);
    if (((width != Tk_ReqWidth(containerPtr->tkwin))
	    || (height != Tk_ReqHeight(containerPtr->tkwin)))
	    && !(containerPtr->flags & DONT_PROPAGATE)) {
	Tk_GeometryRequest(containerPtr->tkwin, width, height);
	if (width>1 && height>1) {
	    masterPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, masterPtr);
	    containerPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, containerPtr);
	}
	masterPtr->abortPtr = NULL;
	Tcl_Release(masterPtr);
	containerPtr->abortPtr = NULL;
	Tcl_Release(containerPtr);
	return;
    }

    /*
     * If the currently requested layout size doesn't match the master's
     * If the currently requested layout size doesn't match the container's
     * window size, then adjust the slot offsets according to the weights. If
     * all of the weights are zero, place the layout according to the anchor
     * value.
     */

    realWidth = Tk_Width(masterPtr->tkwin) -
	    Tk_InternalBorderLeft(masterPtr->tkwin) -
	    Tk_InternalBorderRight(masterPtr->tkwin);
    realHeight = Tk_Height(masterPtr->tkwin) -
	    Tk_InternalBorderTop(masterPtr->tkwin) -
	    Tk_InternalBorderBottom(masterPtr->tkwin);
    realWidth = Tk_Width(containerPtr->tkwin) -
	    Tk_InternalBorderLeft(containerPtr->tkwin) -
	    Tk_InternalBorderRight(containerPtr->tkwin);
    realHeight = Tk_Height(containerPtr->tkwin) -
	    Tk_InternalBorderTop(containerPtr->tkwin) -
	    Tk_InternalBorderBottom(containerPtr->tkwin);
    usedX = AdjustOffsets(realWidth,
	    MAX(slotPtr->columnEnd, slotPtr->columnMax), slotPtr->columnPtr);
    usedY = AdjustOffsets(realHeight, MAX(slotPtr->rowEnd, slotPtr->rowMax),
	    slotPtr->rowPtr);
    TkComputeAnchor(masterPtr->masterDataPtr->anchor, masterPtr->tkwin,
    TkComputeAnchor(containerPtr->containerDataPtr->anchor, containerPtr->tkwin,
	    0, 0, usedX, usedY, &slotPtr->startX, &slotPtr->startY);

    /*
     * Now adjust the actual size of the slave to its cavity by computing the
     * Now adjust the actual size of the content to its cavity by computing the
     * cavity size, and adjusting the widget according to its stickyness.
     */

    for (slavePtr = masterPtr->slavePtr; slavePtr != NULL && !abort;
	    slavePtr = slavePtr->nextPtr) {
    for (contentPtr = containerPtr->contentPtr; contentPtr != NULL && !abort;
	    contentPtr = contentPtr->nextPtr) {
	int x, y;			/* Top left coordinate */
	int width, height;		/* Slot or slave size */
	int col = slavePtr->column;
	int row = slavePtr->row;
	int col = contentPtr->column;
	int row = contentPtr->row;

	x = (col>0) ? slotPtr->columnPtr[col-1].offset : 0;
	y = (row>0) ? slotPtr->rowPtr[row-1].offset : 0;

	width = slotPtr->columnPtr[slavePtr->numCols+col-1].offset - x;
	height = slotPtr->rowPtr[slavePtr->numRows+row-1].offset - y;
	width = slotPtr->columnPtr[contentPtr->numCols+col-1].offset - x;
	height = slotPtr->rowPtr[contentPtr->numRows+row-1].offset - y;

	x += slotPtr->startX;
	y += slotPtr->startY;

	AdjustForSticky(slavePtr, &x, &y, &width, &height);
	AdjustForSticky(contentPtr, &x, &y, &width, &height);

	/*
	 * Now put the window in the proper spot. (This was taken directly
	 * from tkPack.c.) If the slave is a child of the master, then do this
	 * from tkPack.c.) If the content is a child of the container, then do this
	 * here. Otherwise let Tk_MaintainGeometry do the work.
	 */

	if (masterPtr->tkwin == Tk_Parent(slavePtr->tkwin)) {
	if (containerPtr->tkwin == Tk_Parent(contentPtr->tkwin)) {
	    if ((width <= 0) || (height <= 0)) {
		Tk_UnmapWindow(slavePtr->tkwin);
		Tk_UnmapWindow(contentPtr->tkwin);
	    } else {
		if ((x != Tk_X(slavePtr->tkwin))
			|| (y != Tk_Y(slavePtr->tkwin))
			|| (width != Tk_Width(slavePtr->tkwin))
			|| (height != Tk_Height(slavePtr->tkwin))) {
		    Tk_MoveResizeWindow(slavePtr->tkwin, x, y, width, height);
		if ((x != Tk_X(contentPtr->tkwin))
			|| (y != Tk_Y(contentPtr->tkwin))
			|| (width != Tk_Width(contentPtr->tkwin))
			|| (height != Tk_Height(contentPtr->tkwin))) {
		    Tk_MoveResizeWindow(contentPtr->tkwin, x, y, width, height);
		}
		if (abort) {
		    break;
		}

		/*
		 * Don't map the slave if the master isn't mapped: wait until
		 * the master gets mapped later.
		 * Don't map the content if the container isn't mapped: wait until
		 * the container gets mapped later.
		 */

		if (Tk_IsMapped(masterPtr->tkwin)) {
		    Tk_MapWindow(slavePtr->tkwin);
		if (Tk_IsMapped(containerPtr->tkwin)) {
		    Tk_MapWindow(contentPtr->tkwin);
		}
	    }
	} else if ((width <= 0) || (height <= 0)) {
	    Tk_UnmaintainGeometry(slavePtr->tkwin, masterPtr->tkwin);
	    Tk_UnmapWindow(slavePtr->tkwin);
	    Tk_UnmaintainGeometry(contentPtr->tkwin, containerPtr->tkwin);
	    Tk_UnmapWindow(contentPtr->tkwin);
	} else {
	    Tk_MaintainGeometry(slavePtr->tkwin, masterPtr->tkwin, x, y,
	    Tk_MaintainGeometry(contentPtr->tkwin, containerPtr->tkwin, x, y,
		    width, height);
	}
    }

    masterPtr->abortPtr = NULL;
    Tcl_Release(masterPtr);
    containerPtr->abortPtr = NULL;
    Tcl_Release(containerPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ResolveConstraints --
 *
 *	Resolve all of the column and row boundaries. Most of the calculations
 *	are identical for rows and columns, so this procedure is called twice,
 *	once for rows, and again for columns.
 *
 * Results:
 *	The offset (in pixels) from the left/top edge of this layout is
 *	returned.
 *
 * Side effects:
 *	The slot offsets are copied into the SlotInfo structure for the
 *	geometry master.
 *	geometry container.
 *
 *----------------------------------------------------------------------
 */

static int
ResolveConstraints(
    Gridder *masterPtr,		/* The geometry master for this grid. */
    Gridder *containerPtr,		/* The geometry container for this grid. */
    int slotType,		/* Either ROW or COLUMN. */
    int maxOffset)		/* The actual maximum size of this layout in
				 * pixels, or 0 (not currently used). */
{
    SlotInfo *slotPtr;	/* Pointer to row/col constraints. */
    Gridder *slavePtr;	/* List of slave windows in this grid. */
    Gridder *contentPtr;	/* List of content windows in this grid. */
    int constraintCount;	/* Count of rows or columns that have
				 * constraints. */
    int slotCount;		/* Last occupied row or column. */
    int gridCount;		/* The larger of slotCount and
				 * constraintCount. */
    GridLayout *layoutPtr;	/* Temporary layout structure. */
    int requiredSize;		/* The natural size of the grid (pixels).
				 * This is the minimum size needed to
				 * accommodate all of the slaves at their
				 * accommodate all of the content at their
				 * requested sizes. */
    int offset;			/* The pixel offset of the right edge of the
				 * current slot from the beginning of the
				 * layout. */
    int slot;			/* The current slot. */
    int start;			/* The first slot of a contiguous set whose
				 * constraints are not yet fully resolved. */
    int end;			/* The Last slot of a contiguous set whose
				 * constraints are not yet fully resolved. */
    UniformGroup uniformPre[UNIFORM_PREALLOC];
				/* Pre-allocated space for uniform groups. */
    UniformGroup *uniformGroupPtr;
				/* Uniform groups data. */
    int uniformGroups;		/* Number of currently used uniform groups. */
    int uniformGroupsAlloced;	/* Size of allocated space for uniform
				 * groups. */
    int weight, minSize;
    int minSize;
    int prevGrow, accWeight, grow;

    /*
     * For typical sized tables, we'll use stack space for the layout data to
     * avoid the overhead of a malloc and free for every layout.
     */

    GridLayout layoutData[TYPICAL_SIZE + 1];

    if (slotType == COLUMN) {
	constraintCount = masterPtr->masterDataPtr->columnMax;
	slotCount = masterPtr->masterDataPtr->columnEnd;
	slotPtr = masterPtr->masterDataPtr->columnPtr;
	constraintCount = containerPtr->containerDataPtr->columnMax;
	slotCount = containerPtr->containerDataPtr->columnEnd;
	slotPtr = containerPtr->containerDataPtr->columnPtr;
    } else {
	constraintCount = masterPtr->masterDataPtr->rowMax;
	slotCount = masterPtr->masterDataPtr->rowEnd;
	slotPtr = masterPtr->masterDataPtr->rowPtr;
	constraintCount = containerPtr->containerDataPtr->rowMax;
	slotCount = containerPtr->containerDataPtr->rowEnd;
	slotPtr = containerPtr->containerDataPtr->rowPtr;
    }

    /*
     * Make sure there is enough memory for the layout.
     */

    gridCount = MAX(constraintCount, slotCount);
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
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







-
-
+
+



-
+

-
+




-
-
-
+
+
+

-
-
-
-
-
+
+
+
+
+

-
+








-
-
-
+
+
+

-
-
-
-
-
+
+
+
+
+

-
+




















+







	layoutPtr[slot].uniform = NULL;
	layoutPtr[slot].pad = 0;
	layoutPtr[slot].binNextPtr = NULL;
    }

    /*
     * Step 2.
     * Slaves with a span of 1 are used to determine the minimum size of each
     * slot. Slaves whose span is two or more slots don't contribute to the
     * Content with a span of 1 are used to determine the minimum size of each
     * slot. Content whose span is two or more slots don't contribute to the
     * minimum size of each slot directly, but can cause slots to grow if
     * their size exceeds the the sizes of the slots they span.
     *
     * Bin all slaves whose spans are > 1 by their right edges. This allows
     * Bin all content whose spans are > 1 by their right edges. This allows
     * the computation on minimum and maximum possible layout sizes at each
     * slot boundary, without the need to re-sort the slaves.
     * slot boundary, without the need to re-sort the content.
     */

    switch (slotType) {
    case COLUMN:
	for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
		slavePtr = slavePtr->nextPtr) {
	    int rightEdge = slavePtr->column + slavePtr->numCols - 1;
	for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
		contentPtr = contentPtr->nextPtr) {
	    int rightEdge = contentPtr->column + contentPtr->numCols - 1;

	    slavePtr->size = Tk_ReqWidth(slavePtr->tkwin) + slavePtr->padX
		    + slavePtr->iPadX + slavePtr->doubleBw;
	    if (slavePtr->numCols > 1) {
		slavePtr->binNextPtr = layoutPtr[rightEdge].binNextPtr;
		layoutPtr[rightEdge].binNextPtr = slavePtr;
	    contentPtr->size = Tk_ReqWidth(contentPtr->tkwin) + contentPtr->padX
		    + contentPtr->iPadX + contentPtr->doubleBw;
	    if (contentPtr->numCols > 1) {
		contentPtr->binNextPtr = layoutPtr[rightEdge].binNextPtr;
		layoutPtr[rightEdge].binNextPtr = contentPtr;
	    } else if (rightEdge >= 0) {
		int size = slavePtr->size + layoutPtr[rightEdge].pad;
		int size = contentPtr->size + layoutPtr[rightEdge].pad;

		if (size > layoutPtr[rightEdge].minSize) {
		    layoutPtr[rightEdge].minSize = size;
		}
	    }
	}
	break;
    case ROW:
	for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
		slavePtr = slavePtr->nextPtr) {
	    int rightEdge = slavePtr->row + slavePtr->numRows - 1;
	for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
		contentPtr = contentPtr->nextPtr) {
	    int rightEdge = contentPtr->row + contentPtr->numRows - 1;

	    slavePtr->size = Tk_ReqHeight(slavePtr->tkwin) + slavePtr->padY
		    + slavePtr->iPadY + slavePtr->doubleBw;
	    if (slavePtr->numRows > 1) {
		slavePtr->binNextPtr = layoutPtr[rightEdge].binNextPtr;
		layoutPtr[rightEdge].binNextPtr = slavePtr;
	    contentPtr->size = Tk_ReqHeight(contentPtr->tkwin) + contentPtr->padY
		    + contentPtr->iPadY + contentPtr->doubleBw;
	    if (contentPtr->numRows > 1) {
		contentPtr->binNextPtr = layoutPtr[rightEdge].binNextPtr;
		layoutPtr[rightEdge].binNextPtr = contentPtr;
	    } else if (rightEdge >= 0) {
		int size = slavePtr->size + layoutPtr[rightEdge].pad;
		int size = contentPtr->size + layoutPtr[rightEdge].pad;

		if (size > layoutPtr[rightEdge].minSize) {
		    layoutPtr[rightEdge].minSize = size;
		}
	    }
	}
	break;
    }

    /*
     * Step 2b.
     * Consider demands on uniform sizes.
     */

    uniformGroupPtr = uniformPre;
    uniformGroupsAlloced = UNIFORM_PREALLOC;
    uniformGroups = 0;

    for (slot = 0; slot < gridCount; slot++) {
	if (layoutPtr[slot].uniform != NULL) {
		int weight;
	    for (start = 0; start < uniformGroups; start++) {
		if (uniformGroupPtr[start].group == layoutPtr[slot].uniform) {
		    break;
		}
	    }
	    if (start >= uniformGroups) {
		/*
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
2120
2121
2122
2123
2124
2125
2126

2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144

2145
2146
2147
2148
2149


2150
2151
2152


2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164

2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185


2186
2187
2188


2189
2190
2191
2192
2193
2194
2195
2196
2197







-
+

















-
+




-
-
+
+

-
-
+
+










-
+




















-
-
+
+

-
-
+
+








    if (uniformGroups > 0) {
	for (slot = 0; slot < gridCount; slot++) {
	    if (layoutPtr[slot].uniform != NULL) {
		for (start = 0; start < uniformGroups; start++) {
		    if (uniformGroupPtr[start].group ==
			    layoutPtr[slot].uniform) {
			weight = layoutPtr[slot].weight;
			int weight = layoutPtr[slot].weight;
			weight = weight > 0 ? weight : 1;
			layoutPtr[slot].minSize =
				uniformGroupPtr[start].minSize * weight;
			break;
		    }
		}
	    }
	}
    }

    if (uniformGroupPtr != uniformPre) {
	ckfree(uniformGroupPtr);
    }

    /*
     * Step 3.
     * Determine the minimum slot offsets going from left to right that would
     * fit all of the slaves. This determines the minimum
     * fit all of the content. This determines the minimum
     */

    for (offset=0,slot=0; slot < gridCount; slot++) {
	layoutPtr[slot].minOffset = layoutPtr[slot].minSize + offset;
	for (slavePtr = layoutPtr[slot].binNextPtr; slavePtr != NULL;
		slavePtr = slavePtr->binNextPtr) {
	for (contentPtr = layoutPtr[slot].binNextPtr; contentPtr != NULL;
		contentPtr = contentPtr->binNextPtr) {
	    int span = (slotType == COLUMN) ?
		    slavePtr->numCols : slavePtr->numRows;
	    int required = slavePtr->size + layoutPtr[slot - span].minOffset;
		    contentPtr->numCols : contentPtr->numRows;
	    int required = contentPtr->size + layoutPtr[slot - span].minOffset;

	    if (required > layoutPtr[slot].minOffset) {
		layoutPtr[slot].minOffset = required;
	    }
	}
	offset = layoutPtr[slot].minOffset;
    }

    /*
     * At this point, we know the minimum required size of the entire layout.
     * It might be prudent to stop here if our "master" will resize itself to
     * It might be prudent to stop here if our "container" will resize itself to
     * this size.
     */

    requiredSize = offset;
    if (maxOffset > offset) {
	offset=maxOffset;
    }

    /*
     * Step 4.
     * Determine the minimum slot offsets going from right to left, bounding
     * the pixel range of each slot boundary. Pre-fill all of the right
     * offsets with the actual size of the table; they will be reduced as
     * required.
     */

    for (slot=0; slot < gridCount; slot++) {
	layoutPtr[slot].maxOffset = offset;
    }
    for (slot=gridCount-1; slot > 0;) {
	for (slavePtr = layoutPtr[slot].binNextPtr; slavePtr != NULL;
		slavePtr = slavePtr->binNextPtr) {
	for (contentPtr = layoutPtr[slot].binNextPtr; contentPtr != NULL;
		contentPtr = contentPtr->binNextPtr) {
	    int span = (slotType == COLUMN) ?
		    slavePtr->numCols : slavePtr->numRows;
	    int require = offset - slavePtr->size;
		    contentPtr->numCols : contentPtr->numRows;
	    int require = offset - contentPtr->size;
	    int startSlot = slot - span;

	    if (startSlot >=0 && require < layoutPtr[startSlot].maxOffset) {
		layoutPtr[startSlot].maxOffset = require;
	    }
	}
	offset -= layoutPtr[slot].minSize;
2381
2382
2383
2384
2385
2386
2387
2388

2389
2390
2391
2392
2393
2394
2395
2393
2394
2395
2396
2397
2398
2399

2400
2401
2402
2403
2404
2405
2406
2407







-
+







	    }
	}
    }

    /*
     * Step 6.
     * All of the space has been apportioned; copy the layout information back
     * into the master.
     * into the container.
     */

    for (slot=0; slot < gridCount; slot++) {
	slotPtr[slot].offset = layoutPtr[slot].minOffset;
    }

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







-
-
+
+

-
+



















-
+











-
+





-
+








-
+

-
+


-
-
-
-
+
+
+
+

-
-
-
-
+
+
+
+





-
+

-
+






-
+





-
+

-
+





-
-
+
+








-
-
+
+






-
+

-
+






-
+





-
+

-
+





-
-
+
+








-
-
+
+















-
+









-
+















-
+









-
-
-
+
+
+



-
-
+
+






-
-
+
+





-
-
+
+

-
-
+
+




-
+

-
+









-
+


-
+





-
+






-
-
+
+

-
-
-
+
+
+








    hPtr = Tcl_CreateHashEntry(&dispPtr->gridHashTable, (char*) tkwin, &isNew);
    if (!isNew) {
	return (Gridder *)Tcl_GetHashValue(hPtr);
    }
    gridPtr = (Gridder *)ckalloc(sizeof(Gridder));
    gridPtr->tkwin = tkwin;
    gridPtr->masterPtr = NULL;
    gridPtr->masterDataPtr = NULL;
    gridPtr->containerPtr = NULL;
    gridPtr->containerDataPtr = NULL;
    gridPtr->nextPtr = NULL;
    gridPtr->slavePtr = NULL;
    gridPtr->contentPtr = NULL;
    gridPtr->binNextPtr = NULL;

    gridPtr->column = -1;
    gridPtr->row = -1;
    gridPtr->numCols = 1;
    gridPtr->numRows = 1;

    gridPtr->padX = 0;
    gridPtr->padY = 0;
    gridPtr->padLeft = 0;
    gridPtr->padTop = 0;
    gridPtr->iPadX = 0;
    gridPtr->iPadY = 0;
    gridPtr->doubleBw = 2 * Tk_Changes(tkwin)->border_width;
    gridPtr->abortPtr = NULL;
    gridPtr->flags = 0;
    gridPtr->sticky = 0;
    gridPtr->size = 0;
    gridPtr->in = NULL;
    gridPtr->masterDataPtr = NULL;
    gridPtr->containerDataPtr = NULL;
    Tcl_SetHashValue(hPtr, gridPtr);
    Tk_CreateEventHandler(tkwin, StructureNotifyMask,
	    GridStructureProc, gridPtr);
    return gridPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * SetGridSize --
 *
 *	This internal procedure sets the size of the grid occupied by slaves.
 *	This internal procedure sets the size of the grid occupied by content.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	The width and height arguments are filled in the master data
 *	The width and height arguments are filled in the container data
 *	structure. Additional space is allocated for the constraints to
 *	accommodate the offsets.
 *
 *----------------------------------------------------------------------
 */

static void
SetGridSize(
    Gridder *masterPtr)		/* The geometry master for this grid. */
    Gridder *containerPtr)		/* The geometry container for this grid. */
{
    Gridder *slavePtr;	/* Current slave window. */
    Gridder *contentPtr;	/* Current content window. */
    int maxX = 0, maxY = 0;

    for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
	    slavePtr = slavePtr->nextPtr) {
	maxX = MAX(maxX, slavePtr->numCols + slavePtr->column);
	maxY = MAX(maxY, slavePtr->numRows + slavePtr->row);
    for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
	    contentPtr = contentPtr->nextPtr) {
	maxX = MAX(maxX, contentPtr->numCols + contentPtr->column);
	maxY = MAX(maxY, contentPtr->numRows + contentPtr->row);
    }
    masterPtr->masterDataPtr->columnEnd = maxX;
    masterPtr->masterDataPtr->rowEnd = maxY;
    CheckSlotData(masterPtr, maxX, COLUMN, CHECK_SPACE);
    CheckSlotData(masterPtr, maxY, ROW, CHECK_SPACE);
    containerPtr->containerDataPtr->columnEnd = maxX;
    containerPtr->containerDataPtr->rowEnd = maxY;
    CheckSlotData(containerPtr, maxX, COLUMN, CHECK_SPACE);
    CheckSlotData(containerPtr, maxY, ROW, CHECK_SPACE);
}

/*
 *----------------------------------------------------------------------
 *
 * SetSlaveColumn --
 * SetContentColumn --
 *
 *	Update column data for a slave, checking that MAX_ELEMENT bound
 *	Update column data for a content, checking that MAX_ELEMENT bound
 *      is not passed.
 *
 * Results:
 *	TCL_ERROR if out of bounds, TCL_OK otherwise
 *
 * Side effects:
 *	Slave fields are updated.
 *	Content fields are updated.
 *
 *----------------------------------------------------------------------
 */

static int
SetSlaveColumn(
SetContentColumn(
    Tcl_Interp *interp,		/* Interp for error message. */
    Gridder *slavePtr,		/* Slave to be updated. */
    Gridder *contentPtr,		/* Content to be updated. */
    int column,			/* New column or -1 to be unchanged. */
    int numCols)		/* New columnspan or -1 to be unchanged. */
{
    int newColumn, newNumCols, lastCol;

    newColumn = (column >= 0) ? column : slavePtr->column;
    newNumCols = (numCols >= 1) ? numCols : slavePtr->numCols;
    newColumn = (column >= 0) ? column : contentPtr->column;
    newNumCols = (numCols >= 1) ? numCols : contentPtr->numCols;

    lastCol = ((newColumn >= 0) ? newColumn : 0) + newNumCols;
    if (lastCol >= MAX_ELEMENT) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("column out of bounds",-1));
	Tcl_SetErrorCode(interp, "TK", "GRID", "BAD_COLUMN", NULL);
	return TCL_ERROR;
    }

    slavePtr->column = newColumn;
    slavePtr->numCols = newNumCols;
    contentPtr->column = newColumn;
    contentPtr->numCols = newNumCols;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * SetSlaveRow --
 * SetContentRow --
 *
 *	Update row data for a slave, checking that MAX_ELEMENT bound
 *	Update row data for a content, checking that MAX_ELEMENT bound
 *      is not passed.
 *
 * Results:
 *	TCL_ERROR if out of bounds, TCL_OK otherwise
 *
 * Side effects:
 *	Slave fields are updated.
 *	Content fields are updated.
 *
 *----------------------------------------------------------------------
 */

static int
SetSlaveRow(
SetContentRow(
    Tcl_Interp *interp,		/* Interp for error message. */
    Gridder *slavePtr,		/* Slave to be updated. */
    Gridder *contentPtr,		/* Content to be updated. */
    int row,			/* New row or -1 to be unchanged. */
    int numRows)		/* New rowspan or -1 to be unchanged. */
{
    int newRow, newNumRows, lastRow;

    newRow = (row >= 0) ? row : slavePtr->row;
    newNumRows = (numRows >= 1) ? numRows : slavePtr->numRows;
    newRow = (row >= 0) ? row : contentPtr->row;
    newNumRows = (numRows >= 1) ? numRows : contentPtr->numRows;

    lastRow = ((newRow >= 0) ? newRow : 0) + newNumRows;
    if (lastRow >= MAX_ELEMENT) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("row out of bounds", -1));
	Tcl_SetErrorCode(interp, "TK", "GRID", "BAD_ROW", NULL);
	return TCL_ERROR;
    }

    slavePtr->row = newRow;
    slavePtr->numRows = newNumRows;
    contentPtr->row = newRow;
    contentPtr->numRows = newNumRows;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * CheckSlotData --
 *
 *	This internal procedure is used to manage the storage for row and
 *	column (slot) constraints.
 *
 * Results:
 *	TRUE if the index is OK, False otherwise.
 *
 * Side effects:
 *	A new master grid structure may be created. If so, then it is
 *	A new container grid structure may be created. If so, then it is
 *	initialized. In addition, additional storage for a row or column
 *	constraints may be allocated, and the constraint maximums are
 *	adjusted.
 *
 *----------------------------------------------------------------------
 */

static int
CheckSlotData(
    Gridder *masterPtr,		/* The geometry master for this grid. */
    Gridder *containerPtr,		/* The geometry container for this grid. */
    int slot,			/* Which slot to look at. */
    int slotType,		/* ROW or COLUMN. */
    int checkOnly)		/* Don't allocate new space if true. */
{
    int numSlot;		/* Number of slots already allocated (Space) */
    int end;			/* Last used constraint. */

    /*
     * If slot is out of bounds, return immediately.
     */

    if (slot < 0 || slot >= MAX_ELEMENT) {
	return TCL_ERROR;
    }

    if ((checkOnly == CHECK_ONLY) && (masterPtr->masterDataPtr == NULL)) {
    if ((checkOnly == CHECK_ONLY) && (containerPtr->containerDataPtr == NULL)) {
	return TCL_ERROR;
    }

    /*
     * If we need to allocate more space, allocate a little extra to avoid
     * repeated re-alloc's for large tables. We need enough space to hold all
     * of the offsets as well.
     */

    InitMasterData(masterPtr);
    end = (slotType == ROW) ? masterPtr->masterDataPtr->rowMax :
	    masterPtr->masterDataPtr->columnMax;
    InitContainerData(containerPtr);
    end = (slotType == ROW) ? containerPtr->containerDataPtr->rowMax :
	    containerPtr->containerDataPtr->columnMax;
    if (checkOnly == CHECK_ONLY) {
    	return ((end < slot) ? TCL_ERROR : TCL_OK);
    } else {
    	numSlot = (slotType == ROW) ? masterPtr->masterDataPtr->rowSpace
		: masterPtr->masterDataPtr->columnSpace;
    	numSlot = (slotType == ROW) ? containerPtr->containerDataPtr->rowSpace
		: containerPtr->containerDataPtr->columnSpace;
    	if (slot >= numSlot) {
	    int newNumSlot = slot + PREALLOC;
	    size_t oldSize = numSlot * sizeof(SlotInfo);
	    size_t newSize = newNumSlot * sizeof(SlotInfo);
	    SlotInfo *newSI = (SlotInfo *)ckalloc(newSize);
	    SlotInfo *oldSI = (slotType == ROW)
		    ? masterPtr->masterDataPtr->rowPtr
		    : masterPtr->masterDataPtr->columnPtr;
		    ? containerPtr->containerDataPtr->rowPtr
		    : containerPtr->containerDataPtr->columnPtr;

	    memcpy(newSI, oldSI, oldSize);
	    memset(newSI+numSlot, 0, newSize - oldSize);
	    ckfree(oldSI);
	    if (slotType == ROW) {
	 	masterPtr->masterDataPtr->rowPtr = newSI;
	    	masterPtr->masterDataPtr->rowSpace = newNumSlot;
	 	containerPtr->containerDataPtr->rowPtr = newSI;
	    	containerPtr->containerDataPtr->rowSpace = newNumSlot;
	    } else {
	    	masterPtr->masterDataPtr->columnPtr = newSI;
	    	masterPtr->masterDataPtr->columnSpace = newNumSlot;
	    	containerPtr->containerDataPtr->columnPtr = newSI;
	    	containerPtr->containerDataPtr->columnSpace = newNumSlot;
	    }
	}
	if (slot >= end && checkOnly != CHECK_SPACE) {
	    if (slotType == ROW) {
		masterPtr->masterDataPtr->rowMax = slot+1;
		containerPtr->containerDataPtr->rowMax = slot+1;
	    } else {
		masterPtr->masterDataPtr->columnMax = slot+1;
		containerPtr->containerDataPtr->columnMax = slot+1;
	    }
	}
    	return TCL_OK;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * InitMasterData --
 * InitContainerData --
 *
 *	This internal procedure is used to allocate and initialize the data
 *	for a geometry master, if the data doesn't exist already.
 *	for a geometry container, if the data doesn't exist already.
 *
 * Results:
 *	none
 *
 * Side effects:
 *	A new master grid structure may be created. If so, then it is
 *	A new container grid structure may be created. If so, then it is
 *	initialized.
 *
 *----------------------------------------------------------------------
 */

static void
InitMasterData(
    Gridder *masterPtr)
InitContainerData(
    Gridder *containerPtr)
{
    if (masterPtr->masterDataPtr == NULL) {
	GridMaster *gridPtr = masterPtr->masterDataPtr = (GridMaster *)
		ckalloc(sizeof(GridMaster));
    if (containerPtr->containerDataPtr == NULL) {
	GridContainer *gridPtr = containerPtr->containerDataPtr = (GridContainer *)
		ckalloc(sizeof(GridContainer));
	size_t size = sizeof(SlotInfo) * TYPICAL_SIZE;

	gridPtr->columnEnd = 0;
	gridPtr->columnMax = 0;
	gridPtr->columnPtr = (SlotInfo *)ckalloc(size);
	gridPtr->columnSpace = TYPICAL_SIZE;
	gridPtr->rowEnd = 0;
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
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







-
+





-
+







-
+

-
+

-
-
+
+



-
-
+
+

-
-
+
+


-
-
+
+




-
-
-
+
+
+

-
-
+
+


-
-
+
+


-
+


-
+



-
-
-
-
+
+
+
+











-
+

















-
-
-
+
+
+

-
-
+
+

-
+




















-
+














-
+




-
+

-
+

-
-
+
+



-
+

-
+


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









-
+





-
+

-
-
-
+
+
+







-
+


-
-
+
+







-
+





-
+


-
+






-
-
-
-
+
+
+
+







}

/*
 *----------------------------------------------------------------------
 *
 * Unlink --
 *
 *	Remove a grid from its master's list of slaves.
 *	Remove a grid from its container's list of content.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The master will be scheduled for re-arranging, and the size of the
 *	The container will be scheduled for re-arranging, and the size of the
 *	grid will be adjusted accordingly
 *
 *----------------------------------------------------------------------
 */

static void
Unlink(
    Gridder *slavePtr)	/* Window to unlink. */
    Gridder *contentPtr)	/* Window to unlink. */
{
    Gridder *masterPtr, *slavePtr2;
    Gridder *containerPtr, *contentPtr2;

    masterPtr = slavePtr->masterPtr;
    if (masterPtr == NULL) {
    containerPtr = contentPtr->containerPtr;
    if (containerPtr == NULL) {
	return;
    }

    if (masterPtr->slavePtr == slavePtr) {
	masterPtr->slavePtr = slavePtr->nextPtr;
    if (containerPtr->contentPtr == contentPtr) {
	containerPtr->contentPtr = contentPtr->nextPtr;
    } else {
	for (slavePtr2=masterPtr->slavePtr ; ; slavePtr2=slavePtr2->nextPtr) {
	    if (slavePtr2 == NULL) {
	for (contentPtr2=containerPtr->contentPtr ; ; contentPtr2=contentPtr2->nextPtr) {
	    if (contentPtr2 == NULL) {
		Tcl_Panic("Unlink couldn't find previous window");
	    }
	    if (slavePtr2->nextPtr == slavePtr) {
		slavePtr2->nextPtr = slavePtr->nextPtr;
	    if (contentPtr2->nextPtr == contentPtr) {
		contentPtr2->nextPtr = contentPtr->nextPtr;
		break;
	    }
	}
    }
    if (!(masterPtr->flags & REQUESTED_RELAYOUT)) {
	masterPtr->flags |= REQUESTED_RELAYOUT;
	Tcl_DoWhenIdle(ArrangeGrid, masterPtr);
    if (!(containerPtr->flags & REQUESTED_RELAYOUT)) {
	containerPtr->flags |= REQUESTED_RELAYOUT;
	Tcl_DoWhenIdle(ArrangeGrid, containerPtr);
    }
    if (masterPtr->abortPtr != NULL) {
	*masterPtr->abortPtr = 1;
    if (containerPtr->abortPtr != NULL) {
	*containerPtr->abortPtr = 1;
    }

    SetGridSize(slavePtr->masterPtr);
    slavePtr->masterPtr = NULL;
    SetGridSize(contentPtr->containerPtr);
    contentPtr->containerPtr = NULL;

    /*
     * If we have emptied this master from slaves it means we are no longer
     * 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 master to inform it about there
     * Send the event "NoManagedChild" to the container to inform it about there
     * being no managed children inside it.
     */

    if ((masterPtr->slavePtr == NULL) && (masterPtr->flags & ALLOCED_MASTER)) {
	TkFreeGeometryMaster(masterPtr->tkwin, "grid");
	masterPtr->flags &= ~ALLOCED_MASTER;
	TkSendVirtualEvent(masterPtr->tkwin, "NoManagedChild", NULL);
    if ((containerPtr->contentPtr == NULL) && (containerPtr->flags & ALLOCED_CONTAINER)) {
	TkFreeGeometryContainer(containerPtr->tkwin, "grid");
	containerPtr->flags &= ~ALLOCED_CONTAINER;
	Tk_SendVirtualEvent(containerPtr->tkwin, "NoManagedChild", NULL);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyGrid --
 *
 *	This procedure is invoked by Tcl_EventuallyFree or Tcl_Release to
 *	clean up the internal structure of a grid at a safe time (when no-one
 *	is using it anymore). Cleaning up the grid involves freeing the main
 *	structure for all windows and the master structure for geometry
 *	structure for all windows and the container structure for geometry
 *	managers.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Everything associated with the grid is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyGrid(
    void *memPtr)		/* Info about window that is now dead. */
{
    Gridder *gridPtr = (Gridder *)memPtr;

    if (gridPtr->masterDataPtr != NULL) {
	if (gridPtr->masterDataPtr->rowPtr != NULL) {
	    ckfree(gridPtr->masterDataPtr -> rowPtr);
    if (gridPtr->containerDataPtr != NULL) {
	if (gridPtr->containerDataPtr->rowPtr != NULL) {
	    ckfree(gridPtr->containerDataPtr -> rowPtr);
	}
	if (gridPtr->masterDataPtr->columnPtr != NULL) {
	    ckfree(gridPtr->masterDataPtr -> columnPtr);
	if (gridPtr->containerDataPtr->columnPtr != NULL) {
	    ckfree(gridPtr->containerDataPtr -> columnPtr);
	}
	ckfree(gridPtr->masterDataPtr);
	ckfree(gridPtr->containerDataPtr);
    }
    if (gridPtr->in != NULL) {
	Tcl_DecrRefCount(gridPtr->in);
    }
    ckfree(gridPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * GridStructureProc --
 *
 *	This procedure is invoked by the Tk event dispatcher in response to
 *	StructureNotify events.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	If a window was just deleted, clean up all its grid-related
 *	information. If it was just resized, re-configure its slaves, if any.
 *	information. If it was just resized, re-configure its content, if any.
 *
 *----------------------------------------------------------------------
 */

static void
GridStructureProc(
    ClientData clientData,	/* Our information about window referred to by
				 * eventPtr. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    Gridder *gridPtr = (Gridder *)clientData;
    TkDisplay *dispPtr = ((TkWindow *) gridPtr->tkwin)->dispPtr;

    if (eventPtr->type == ConfigureNotify) {
	if ((gridPtr->slavePtr != NULL)
	if ((gridPtr->contentPtr != NULL)
		&& !(gridPtr->flags & REQUESTED_RELAYOUT)) {
	    gridPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, gridPtr);
	}
	if ((gridPtr->masterPtr != NULL) &&
	if ((gridPtr->containerPtr != NULL) &&
		(gridPtr->doubleBw != 2*Tk_Changes(gridPtr->tkwin)->border_width)) {
	    if (!(gridPtr->masterPtr->flags & REQUESTED_RELAYOUT)) {
	    if (!(gridPtr->containerPtr->flags & REQUESTED_RELAYOUT)) {
		gridPtr->doubleBw = 2*Tk_Changes(gridPtr->tkwin)->border_width;
		gridPtr->masterPtr->flags |= REQUESTED_RELAYOUT;
		Tcl_DoWhenIdle(ArrangeGrid, gridPtr->masterPtr);
		gridPtr->containerPtr->flags |= REQUESTED_RELAYOUT;
		Tcl_DoWhenIdle(ArrangeGrid, gridPtr->containerPtr);
	    }
	}
    } else if (eventPtr->type == DestroyNotify) {
	Gridder *slavePtr, *nextPtr;
	Gridder *contentPtr, *nextPtr;

	if (gridPtr->masterPtr != NULL) {
	if (gridPtr->containerPtr != NULL) {
	    Unlink(gridPtr);
	}
	for (slavePtr = gridPtr->slavePtr; slavePtr != NULL;
		slavePtr = nextPtr) {
	    Tk_ManageGeometry(slavePtr->tkwin, NULL, NULL);
	    Tk_UnmapWindow(slavePtr->tkwin);
	    slavePtr->masterPtr = NULL;
	    nextPtr = slavePtr->nextPtr;
	    slavePtr->nextPtr = NULL;
	for (contentPtr = gridPtr->contentPtr; contentPtr != NULL;
		contentPtr = nextPtr) {
	    Tk_ManageGeometry(contentPtr->tkwin, NULL, NULL);
	    Tk_UnmapWindow(contentPtr->tkwin);
	    contentPtr->containerPtr = NULL;
	    nextPtr = contentPtr->nextPtr;
	    contentPtr->nextPtr = NULL;
	}
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->gridHashTable,
		gridPtr->tkwin));
	if (gridPtr->flags & REQUESTED_RELAYOUT) {
	    Tcl_CancelIdleCall(ArrangeGrid, gridPtr);
	}
	gridPtr->tkwin = NULL;
	Tcl_EventuallyFree(gridPtr, (Tcl_FreeProc *)DestroyGrid);
    } else if (eventPtr->type == MapNotify) {
	if ((gridPtr->slavePtr != NULL)
	if ((gridPtr->contentPtr != NULL)
		&& !(gridPtr->flags & REQUESTED_RELAYOUT)) {
	    gridPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, gridPtr);
	}
    } else if (eventPtr->type == UnmapNotify) {
	Gridder *slavePtr;
	Gridder *contentPtr;

	for (slavePtr = gridPtr->slavePtr; slavePtr != NULL;
		slavePtr = slavePtr->nextPtr) {
	    Tk_UnmapWindow(slavePtr->tkwin);
	for (contentPtr = gridPtr->contentPtr; contentPtr != NULL;
		contentPtr = contentPtr->nextPtr) {
	    Tk_UnmapWindow(contentPtr->tkwin);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureSlaves --
 * ConfigureContent --
 *
 *	This implements the guts of the "grid configure" command. Given a list
 *	of slaves and configuration options, it arranges for the grid to
 *	manage the slaves and sets the specified options. Arguments consist
 *	of content and configuration options, it arranges for the grid to
 *	manage the content and sets the specified options. Arguments consist
 *	of windows or window shortcuts followed by "-option value" pairs.
 *
 * Results:
 *	TCL_OK is returned if all went well. Otherwise, TCL_ERROR is returned
 *	and the interp's result is set to contain an error message.
 *
 * Side effects:
 *	Slave windows get taken over by the grid.
 *	Content windows get taken over by the grid.
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureSlaves(
ConfigureContent(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Window tkwin,		/* Any window in application containing
				 * slaves. Used to look up slave names. */
				 * content. Used to look up content names. */
    int objc,			/* Number of elements in argv. */
    Tcl_Obj *const objv[])	/* Argument objects: contains one or more
				 * window names followed by any number of
				 * "option value" pairs. Caller must make sure
				 * that there is at least one window name. */
{
    Gridder *masterPtr = NULL;
    Gridder *slavePtr;
    Tk_Window other, slave, parent, ancestor;
    TkWindow *master;
    Gridder *containerPtr = NULL;
    Gridder *contentPtr;
    Tk_Window other, content, parent, ancestor;
    TkWindow *container;
    int i, j, tmp;
    int numWindows;
    int width;
    int defaultRow = -1;
    int defaultColumn = 0;	/* Default column number */
    int defaultColumnSpan = 1;	/* Default number of columns */
    const char *lastWindow;	/* Use this window to base current row/col
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
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







-
+




-
+



-
+


-
+

-
+

-
+


-
-
-
+
+
+

-
-
+
+



-
-
+
+

-
-
+
+







     */

    firstChar = 0;
    for (numWindows=0, i=0; i < objc; i++) {
	TkSizeT 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 slave's
	     * Check that windows are valid, and locate the first content's
	     * parent window (default for -in).
	     */

	    if (TkGetWindowFromObj(interp, tkwin, objv[i], &slave) != TCL_OK) {
	    if (TkGetWindowFromObj(interp, tkwin, objv[i], &content) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (masterPtr == NULL) {
	    if (containerPtr == NULL) {
		/*
		 * Is there any saved -in from a removed slave?
		 * Is there any saved -in from a removed content?
		 * If there is, it becomes default for -in.
		 * If the stored master does not exist, just ignore it.
		 * If the stored container does not exist, just ignore it.
		 */

		struct Gridder *slavePtr = GetGrid(slave);
		if (slavePtr->in != NULL) {
		    if (TkGetWindowFromObj(interp, slave, slavePtr->in, &parent)
		contentPtr = GetGrid(content);
		if (contentPtr->in != NULL) {
		    if (TkGetWindowFromObj(interp, content, contentPtr->in, &parent)
			    == TCL_OK) {
			masterPtr = GetGrid(parent);
			InitMasterData(masterPtr);
			containerPtr = GetGrid(parent);
			InitContainerData(containerPtr);
		    }
		}
	    }
	    if (masterPtr == NULL) {
		parent = Tk_Parent(slave);
	    if (containerPtr == NULL) {
		parent = Tk_Parent(content);
		if (parent != NULL) {
		    masterPtr = GetGrid(parent);
		    InitMasterData(masterPtr);
		    containerPtr = GetGrid(parent);
		    InitContainerData(containerPtr);
		}
	    }
	    numWindows++;
	    continue;
    	}
	if (length > 1 && i == 0) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
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
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







-
-
+
+















-
+



-
-
-
+
+
+






-
-
-
-
+
+
+
+












-
+












-
+






-
+



-
+






-
+




-
+



-
+




















-
+












-
+








-
+






-
-
+
+












-
+



-
+







-
+


-
+







-
+



-
+





-
+












-
+












-
+







-
+



-
-
+
+








-
+




-
+

-
+


-
-
-
-
+
+
+
+


-
-
-
+
+
+

-
-
+
+


-
-
+
+

-
-
-
+
+
+



-
-
+
+



-
+





-
-
+
+

-
+








-
-
-
+
+
+

-
-
+
+

-
+



-
-
+
+


-
+

-
-
+
+

-
-
+
+


-
+






-
-
+
+



-
-
+
+


-
-
+
+



-
+



-
+



-
-
+
+

-
-
-
+
+
+















-
+

-
+










-
+

-
+









-
+







	    return TCL_ERROR;
	}
	if (index == CONF_IN) {
	    if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other) !=
		    TCL_OK) {
		return TCL_ERROR;
	    }
	    masterPtr = GetGrid(other);
	    InitMasterData(masterPtr);
	    containerPtr = GetGrid(other);
	    InitContainerData(containerPtr);
	} else if (index == CONF_ROW) {
	    if (Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK
		    || tmp < 0) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"bad row value \"%s\": must be a non-negative integer",
			Tcl_GetString(objv[i+1])));
		Tcl_SetErrorCode(interp, "TK", "VALUE", "POSITIVE_INT", NULL);
		return TCL_ERROR;
	    }
	    defaultRow = tmp;
	}
    }

    /*
     * If no -row is given, use the next row after the highest occupied row
     * of the master.
     * of the container.
     */

    if (defaultRow < 0) {
	if (masterPtr != NULL && masterPtr->masterDataPtr != NULL) {
	    SetGridSize(masterPtr);
	    defaultRow = masterPtr->masterDataPtr->rowEnd;
	if (containerPtr != NULL && containerPtr->containerDataPtr != NULL) {
	    SetGridSize(containerPtr);
	    defaultRow = containerPtr->containerDataPtr->rowEnd;
	} else {
	    defaultRow = 0;
	}
    }

    /*
     * Iterate over all of the slave windows and short-cuts, parsing options
     * for each slave. It's a bit wasteful to re-parse the options for each
     * slave, but things get too messy if we try to parse the arguments just
     * once at the beginning. For example, if a slave already is managed we
     * Iterate over all of the content windows and short-cuts, parsing options
     * for each content. It's a bit wasteful to re-parse the options for each
     * content, but things get too messy if we try to parse the arguments just
     * once at the beginning. For example, if a content already is managed we
     * want to just change a few existing values without resetting everything.
     * If there are multiple windows, the -in option only gets processed for
     * the first window.
     */

    positionGiven = 0;
    for (j = 0; j < numWindows; j++) {
	string = Tcl_GetString(objv[j]);
    	firstChar = string[0];

	/*
	 * '^' and 'x' cause us to skip a column. '-' is processed as part of
	 * its preceeding slave.
	 * its preceeding content.
	 */

	if ((firstChar == REL_VERT) || (firstChar == REL_SKIP)) {
	    defaultColumn++;
	    continue;
	}
	if (firstChar == REL_HORIZ) {
	    continue;
	}

	for (defaultColumnSpan = 1; j + defaultColumnSpan < numWindows;
		defaultColumnSpan++) {
	    const char *string = Tcl_GetString(objv[j + defaultColumnSpan]);
	    string = Tcl_GetString(objv[j + defaultColumnSpan]);

	    if (*string != REL_HORIZ) {
		break;
	    }
	}

	if (TkGetWindowFromObj(interp, tkwin, objv[j], &slave) != TCL_OK) {
	if (TkGetWindowFromObj(interp, tkwin, objv[j], &content) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (Tk_TopWinHierarchy(slave)) {
	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;
	}
	slavePtr = GetGrid(slave);
	contentPtr = GetGrid(content);

	/*
	 * The following statement is taken from tkPack.c:
	 *
	 * "If the slave isn't currently managed, reset all of its
	 * "If the content isn't currently managed, reset all of its
	 * configuration information to default values (there could be old
	 * values left from a previous packer)."
	 *
	 * I [D.S.] disagree with this statement. If a slave is disabled
	 * I [D.S.] disagree with this statement. If a content is disabled
	 * (using "forget") and then re-enabled, I submit that 90% of the time
	 * the programmer will want it to retain its old configuration
	 * information. If the programmer doesn't want this behavior, then the
	 * defaults can be reestablished by hand, without having to worry
	 * about keeping track of the old state.
	 */

	for (i = numWindows; i < objc; i += 2) {
	    Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings,
		    sizeof(char *), "option", 0, &index);
	    switch ((enum options) index) {
	    case CONF_COLUMN:
		if (Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK
			|| tmp < 0) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad column value \"%s\": must be a non-negative integer",
			    Tcl_GetString(objv[i+1])));
		    Tcl_SetErrorCode(interp, "TK", "VALUE", "COLUMN", NULL);
		    return TCL_ERROR;
		}
		if (SetSlaveColumn(interp, slavePtr, tmp, -1) != TCL_OK) {
		if (SetContentColumn(interp, contentPtr, tmp, -1) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_COLUMNSPAN:
		if (Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK
			|| tmp <= 0) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad columnspan value \"%s\": must be a positive integer",
			    Tcl_GetString(objv[i+1])));
		    Tcl_SetErrorCode(interp, "TK", "VALUE", "SPAN", NULL);
		    return TCL_ERROR;
		}
		if (SetSlaveColumn(interp, slavePtr, -1, tmp) != TCL_OK) {
		if (SetContentColumn(interp, contentPtr, -1, tmp) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_IN:
		if (TkGetWindowFromObj(interp, tkwin, objv[i+1],
			&other) != TCL_OK) {
		    return TCL_ERROR;
		}
		if (other == slave) {
		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;
		masterPtr = GetGrid(other);
		InitMasterData(masterPtr);
		containerPtr = GetGrid(other);
		InitContainerData(containerPtr);
		break;
	    case CONF_STICKY: {
		int sticky = StringToSticky(Tcl_GetString(objv[i+1]));

		if (sticky == -1) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad stickyness value \"%s\": must be"
			    " a string containing n, e, s, and/or w",
			    Tcl_GetString(objv[i+1])));
		    Tcl_SetErrorCode(interp, "TK", "VALUE", "STICKY", NULL);
		    return TCL_ERROR;
		}
		slavePtr->sticky = sticky;
		contentPtr->sticky = sticky;
		break;
	    }
	    case CONF_IPADX:
		if ((Tk_GetPixelsFromObj(NULL, slave, objv[i+1],
		if ((Tk_GetPixelsFromObj(NULL, content, objv[i+1],
			&tmp) != TCL_OK) || (tmp < 0)) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad ipadx value \"%s\": must be positive screen distance",
			    Tcl_GetString(objv[i+1])));
		    Tcl_SetErrorCode(interp, "TK", "VALUE", "INT_PAD", NULL);
		    return TCL_ERROR;
		}
		slavePtr->iPadX = tmp * 2;
		contentPtr->iPadX = tmp * 2;
		break;
	    case CONF_IPADY:
		if ((Tk_GetPixelsFromObj(NULL, slave, objv[i+1],
		if ((Tk_GetPixelsFromObj(NULL, content, objv[i+1],
			&tmp) != TCL_OK) || (tmp < 0)) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad ipady value \"%s\": must be positive screen distance",
			    Tcl_GetString(objv[i+1])));
		    Tcl_SetErrorCode(interp, "TK", "VALUE", "INT_PAD", NULL);
		    return TCL_ERROR;
		}
		slavePtr->iPadY = tmp * 2;
		contentPtr->iPadY = tmp * 2;
		break;
	    case CONF_PADX:
		if (TkParsePadAmount(interp, tkwin, objv[i+1],
			&slavePtr->padLeft, &slavePtr->padX) != TCL_OK) {
			&contentPtr->padLeft, &contentPtr->padX) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_PADY:
		if (TkParsePadAmount(interp, tkwin, objv[i+1],
			&slavePtr->padTop, &slavePtr->padY) != TCL_OK) {
			&contentPtr->padTop, &contentPtr->padY) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_ROW:
		if (Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK
			|| tmp < 0) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad row value \"%s\": must be a non-negative integer",
			    Tcl_GetString(objv[i+1])));
		    Tcl_SetErrorCode(interp, "TK", "VALUE", "COLUMN", NULL);
		    return TCL_ERROR;
		}
		if (SetSlaveRow(interp, slavePtr, tmp, -1) != TCL_OK) {
		if (SetContentRow(interp, contentPtr, tmp, -1) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_ROWSPAN:
		if ((Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK)
			|| tmp <= 0) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad rowspan value \"%s\": must be a positive integer",
			    Tcl_GetString(objv[i+1])));
		    Tcl_SetErrorCode(interp, "TK", "VALUE", "SPAN", NULL);
		    return TCL_ERROR;
		}
		if (SetSlaveRow(interp, slavePtr, -1, tmp) != TCL_OK) {
		if (SetContentRow(interp, contentPtr, -1, tmp) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    }
	}

	/*
	 * If no position was specified via -in and the slave is already
	 * If no position was specified via -in and the content is already
	 * packed, then leave it in its current location.
	 */

    	if (!positionGiven && (slavePtr->masterPtr != NULL)) {
	    masterPtr = slavePtr->masterPtr;
    	if (!positionGiven && (contentPtr->containerPtr != NULL)) {
	    containerPtr = contentPtr->containerPtr;
	    goto scheduleLayout;
    	}

	/*
	 * If the same -in window is passed in again, then just leave it in
	 * its current location.
	 */

	if (positionGiven && (masterPtr == slavePtr->masterPtr)) {
	if (positionGiven && (containerPtr == contentPtr->containerPtr)) {
	    goto scheduleLayout;
	}

	/*
	 * Make sure we have a geometry master. We look at:
	 * Make sure we have a geometry container. We look at:
	 *  1)   the -in flag
	 *  2)   the parent of the first slave.
	 *  2)   the parent of the first content.
	 */

	parent = Tk_Parent(slave);
    	if (masterPtr == NULL) {
	    masterPtr = GetGrid(parent);
	    InitMasterData(masterPtr);
	parent = Tk_Parent(content);
    	if (containerPtr == NULL) {
	    containerPtr = GetGrid(parent);
	    InitContainerData(containerPtr);
    	}

	if (slavePtr->masterPtr != NULL && slavePtr->masterPtr != masterPtr) {
            if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) {
                Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin);
	if (contentPtr->containerPtr != NULL && contentPtr->containerPtr != containerPtr) {
            if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
                Tk_UnmaintainGeometry(contentPtr->tkwin, contentPtr->containerPtr->tkwin);
            }
	    Unlink(slavePtr);
	    slavePtr->masterPtr = NULL;
	    Unlink(contentPtr);
	    contentPtr->containerPtr = NULL;
	}

	if (slavePtr->masterPtr == NULL) {
	    Gridder *tempPtr = masterPtr->slavePtr;
	if (contentPtr->containerPtr == NULL) {
	    Gridder *tempPtr = containerPtr->contentPtr;

	    slavePtr->masterPtr = masterPtr;
	    masterPtr->slavePtr = slavePtr;
	    slavePtr->nextPtr = tempPtr;
	    contentPtr->containerPtr = containerPtr;
	    containerPtr->contentPtr = contentPtr;
	    contentPtr->nextPtr = tempPtr;
	}

	/*
	 * Make sure that the slave's parent is either the master or an
	 * ancestor of the master, and that the master and slave aren't the
	 * Make sure that the content's parent is either the container or an
	 * ancestor of the container, and that the container and content aren't the
	 * same.
	 */

	for (ancestor = masterPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
	for (ancestor = containerPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == parent) {
		break;
	    }
	    if (Tk_TopWinHierarchy(ancestor)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't put %s inside %s", Tcl_GetString(objv[j]),
			Tk_PathName(masterPtr->tkwin)));
			"can't put \"%s\" inside \"%s\"", Tcl_GetString(objv[j]),
			Tk_PathName(containerPtr->tkwin)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL);
		Unlink(slavePtr);
		Unlink(contentPtr);
		return TCL_ERROR;
	    }
	}

	/*
	 * Check for management loops.
	 */

	for (master = (TkWindow *)masterPtr->tkwin; master != NULL;
	     master = (TkWindow *)TkGetGeomMaster(master)) {
	    if (master == (TkWindow *)slave) {
	for (container = (TkWindow *)containerPtr->tkwin; container != NULL;
	     container = (TkWindow *)TkGetContainer(container)) {
	    if (container == (TkWindow *)content) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't put %s inside %s, would cause management loop",
	            Tcl_GetString(objv[j]), Tk_PathName(masterPtr->tkwin)));
		    "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(slavePtr);
		Unlink(contentPtr);
		return TCL_ERROR;
	    }
	}
	if (masterPtr->tkwin != Tk_Parent(slave)) {
	    ((TkWindow *)slave)->maintainerPtr = (TkWindow *)masterPtr->tkwin;
	if (containerPtr->tkwin != Tk_Parent(content)) {
	    ((TkWindow *)content)->maintainerPtr = (TkWindow *)containerPtr->tkwin;
	}

	Tk_ManageGeometry(slave, &gridMgrType, slavePtr);
	Tk_ManageGeometry(content, &gridMgrType, contentPtr);

	if (!(masterPtr->flags & DONT_PROPAGATE)) {
	    if (TkSetGeometryMaster(interp, masterPtr->tkwin, "grid")
	if (!(containerPtr->flags & DONT_PROPAGATE)) {
	    if (TkSetGeometryContainer(interp, containerPtr->tkwin, "grid")
		    != TCL_OK) {
		Tk_ManageGeometry(slave, NULL, NULL);
		Unlink(slavePtr);
		Tk_ManageGeometry(content, NULL, NULL);
		Unlink(contentPtr);
		return TCL_ERROR;
	    }
	    masterPtr->flags |= ALLOCED_MASTER;
	    containerPtr->flags |= ALLOCED_CONTAINER;
	}

	/*
	 * Assign default position information.
	 */

	if (slavePtr->column == -1) {
	    if (SetSlaveColumn(interp, slavePtr, defaultColumn,-1) != TCL_OK){
	if (contentPtr->column == -1) {
	    if (SetContentColumn(interp, contentPtr, defaultColumn,-1) != TCL_OK){
		return TCL_ERROR;
	    }
	}
	if (SetSlaveColumn(interp, slavePtr, -1,
		slavePtr->numCols + defaultColumnSpan - 1) != TCL_OK) {
	if (SetContentColumn(interp, contentPtr, -1,
		contentPtr->numCols + defaultColumnSpan - 1) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (slavePtr->row == -1) {
	    if (SetSlaveRow(interp, slavePtr, defaultRow, -1) != TCL_OK) {
	if (contentPtr->row == -1) {
	    if (SetContentRow(interp, contentPtr, defaultRow, -1) != TCL_OK) {
		return TCL_ERROR;
	    }
	}
	defaultColumn += slavePtr->numCols;
	defaultColumn += contentPtr->numCols;
	defaultColumnSpan = 1;

	/*
	 * Arrange for the master to be re-arranged at the first idle moment.
	 * Arrange for the container to be re-arranged at the first idle moment.
	 */

    scheduleLayout:
	if (masterPtr->abortPtr != NULL) {
	    *masterPtr->abortPtr = 1;
	if (containerPtr->abortPtr != NULL) {
	    *containerPtr->abortPtr = 1;
	}
	if (!(masterPtr->flags & REQUESTED_RELAYOUT)) {
	    masterPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, masterPtr);
	if (!(containerPtr->flags & REQUESTED_RELAYOUT)) {
	    containerPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, containerPtr);
	}
    }

    /*
     * Now look for all the "^"'s.
     */

    lastWindow = NULL;
    numSkip = 0;
    for (j = 0; j < numWindows; j++) {
	struct Gridder *otherPtr;
	int match;			/* Found a match for the ^ */
	int lastRow, lastColumn;	/* Implied end of table. */

	string = Tcl_GetString(objv[j]);
    	firstChar = string[0];
	firstChar = string[0];

    	if (firstChar == '.') {
	if (firstChar == '.') {
	    lastWindow = string;
	    numSkip = 0;
	}
	if (firstChar == REL_SKIP) {
	    numSkip++;
	}
	if (firstChar != REL_VERT) {
	    continue;
	}

	if (masterPtr == NULL) {
	if (containerPtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't use '^', cant find master", -1));
		    "can't use '^', can't find container window", -1));
	    Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Count the number of consecutive ^'s starting from this position.
	 */

	for (width = 1; width + j < numWindows; width++) {
	    const char *string = Tcl_GetString(objv[j+width]);
	    string = Tcl_GetString(objv[j+width]);

	    if (*string != REL_VERT) {
		break;
	    }
	}

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







-
-
+
+

-
-
-
-
-
+
+
+
+
+



-
-
+
+







-
+





-
+

-
+



-
+


-
+


-
+



-
-
-
-
+
+
+
+







	    lastRow = otherPtr->row + otherPtr->numRows - 2;
	    lastColumn = otherPtr->column + otherPtr->numCols;
	}

	lastColumn += numSkip;

	match = 0;
	for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
		slavePtr = slavePtr->nextPtr) {
	for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
		contentPtr = contentPtr->nextPtr) {

	    if (slavePtr->column == lastColumn
		    && slavePtr->row + slavePtr->numRows - 1 == lastRow) {
		if (slavePtr->numCols <= width) {
		    if (SetSlaveRow(interp, slavePtr, -1,
			    slavePtr->numRows + 1) != TCL_OK) {
	    if (contentPtr->column == lastColumn
		    && contentPtr->row + contentPtr->numRows - 1 == lastRow) {
		if (contentPtr->numCols <= width) {
		    if (SetContentRow(interp, contentPtr, -1,
			    contentPtr->numRows + 1) != TCL_OK) {
			return TCL_ERROR;
		    }
		    match++;
		    j += slavePtr->numCols - 1;
		    lastWindow = Tk_PathName(slavePtr->tkwin);
		    j += contentPtr->numCols - 1;
		    lastWindow = Tk_PathName(contentPtr->tkwin);
		    numSkip = 0;
		    break;
		}
	    }
	}
	if (!match) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't find slave to extend with \"^\"", -1));
		    "can't find content to extend with \"^\"", -1));
	    Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	    return TCL_ERROR;
	}
    }

    if (masterPtr == NULL) {
    if (containerPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't determine master window", -1));
		"can't determine container window", -1));
	Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	return TCL_ERROR;
    }
    SetGridSize(masterPtr);
    SetGridSize(containerPtr);

    /*
     * If we have emptied this master from slaves it means we are no longer
     * 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 master to inform it about there
     * Send the event "NoManagedChild" to the container to inform it about there
     * being no managed children inside it.
     */

    if (masterPtr->slavePtr == NULL && masterPtr->flags & ALLOCED_MASTER) {
	TkFreeGeometryMaster(masterPtr->tkwin, "grid");
	masterPtr->flags &= ~ALLOCED_MASTER;
	TkSendVirtualEvent(masterPtr->tkwin, "NoManagedChild", NULL);
    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;
}

/*
 *----------------------------------------------------------------------

Changes to generic/tkImage.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
1
2
3
4
5
6


7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28


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

43
44
45
46
47

48
49
50
51


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

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


85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106

107
108
109
110
111

112
113
114
115
116
117
118






-
-
+
+




















-
-
+
+












-
+




-
+



-
-
+
+













-
+

















-
-
+
+




















-
+




-







/*
 * tkImage.c --
 *
 *	This module implements the image protocol, which allows lots of
 *	different kinds of images to be used in lots of different widgets.
 *
 * Copyright (c) 1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

/*
 * Each call to Tk_GetImage returns a pointer to one of the following
 * structures, which is used as a token by clients (widgets) that display
 * images.
 */

typedef struct Image {
    Tk_Window tkwin;		/* Window passed to Tk_GetImage (needed to
				 * "re-get" the image later if the manager
				 * changes). */
    Display *display;		/* Display for tkwin. Needed because when the
				 * image is eventually freed tkwin may not
				 * exist anymore. */
    struct ImageMaster *masterPtr;
				/* Master for this image (identifiers image
    struct ImageModel *modelPtr;
				/* Model for this image (identifiers image
				 * manager, for example). */
    ClientData instanceData;	/* One word argument to pass to image manager
				 * when dealing with this image instance. */
    Tk_ImageChangedProc *changeProc;
				/* Code in widget to call when image changes
				 * in a way that affects redisplay. */
    ClientData widgetClientData;/* Argument to pass to changeProc. */
    struct Image *nextPtr;	/* Next in list of all image instances
				 * associated with the same name. */
} Image;

/*
 * For each image master there is one of the following structures, which
 * For each image model there is one of the following structures, which
 * represents a name in the image table and all of the images instantiated
 * from it. Entries in mainPtr->imageTable point to these structures.
 */

typedef struct ImageMaster {
typedef struct ImageModel {
    Tk_ImageType *typePtr;	/* Information about image type. NULL means
				 * that no image manager owns this image: the
				 * image was deleted. */
    ClientData masterData;	/* One-word argument to pass to image mgr when
				 * dealing with the master, as opposed to
    ClientData modelData;	/* One-word argument to pass to image mgr when
				 * dealing with the model, as opposed to
				 * instances. */
    int width, height;		/* Last known dimensions for image. */
    Tcl_HashTable *tablePtr;	/* Pointer to hash table containing image (the
				 * imageTable field in some TkMainInfo
				 * structure). */
    Tcl_HashEntry *hPtr;	/* Hash entry in mainPtr->imageTable for this
				 * structure (used to delete the hash
				 * entry). */
    Image *instancePtr;		/* Pointer to first in list of instances
				 * derived from this name. */
    int deleted;		/* Flag set when image is being deleted. */
    TkWindow *winPtr;		/* Main window of interpreter (used to detect
				 * when the world is falling apart.) */
} ImageMaster;
} ImageModel;

typedef struct {
    Tk_ImageType *imageTypeList;/* First in a list of all known image
				 * types. */
    Tk_ImageType *oldImageTypeList;
				/* First in a list of all known old-style
				 * image types. */
    int initialized;		/* Set to 1 if we've initialized the
				 * structure. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Prototypes for local functions:
 */

static void		ImageTypeThreadExitProc(ClientData clientData);
static void		DeleteImage(ImageMaster *masterPtr);
static void		EventuallyDeleteImage(ImageMaster *masterPtr,
static void		DeleteImage(ImageModel *modelPtr);
static void		EventuallyDeleteImage(ImageModel *modelPtr,
			    int forgetImageHashNow);

/*
 *----------------------------------------------------------------------
 *
 * ImageTypeThreadExitProc --
 *
 *	Clean up the registered list of image types.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The thread's linked lists of photo image formats is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ImageTypeThreadExitProc(
    ClientData dummy)	/* not used */
    TCL_UNUSED(void *))
{
    Tk_ImageType *freePtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)dummy;

    while (tsdPtr->oldImageTypeList != NULL) {
	freePtr = tsdPtr->oldImageTypeList;
	tsdPtr->oldImageTypeList = tsdPtr->oldImageTypeList->nextPtr;
	ckfree(freePtr);
    }
    while (tsdPtr->imageTypeList != NULL) {
215
216
217
218
219
220
221
222

223
224
225
226
227
228
229
214
215
216
217
218
219
220

221
222
223
224
225
226
227
228







-
+







    enum options {
	IMAGE_CREATE, IMAGE_DELETE, IMAGE_HEIGHT, IMAGE_INUSE, IMAGE_NAMES,
	IMAGE_TYPE, IMAGE_TYPES, IMAGE_WIDTH
    };
    TkWindow *winPtr = (TkWindow *)clientData;
    int i, isNew, firstOption, index;
    Tk_ImageType *typePtr;
    ImageMaster *masterPtr;
    ImageModel *modelPtr;
    Image *imagePtr;
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    char idString[16 + TCL_INTEGER_SPACE];
    TkDisplay *dispPtr = winPtr->dispPtr;
    const char *arg, *name;
    Tcl_Obj *resultObj;
294
295
296
297
298
299
300
301

302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332











333
334
335
336

337
338
339
340
341



342
343

344
345
346
347


348
349
350


351
352

353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373

374
375
376
377



378
379
380
381
382
383

384
385
386
387
388


389
390
391

392
393
394
395
396
397
398
399
400
401
402
403
404
405


406
407
408

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


421
422
423
424
425
426
427
293
294
295
296
297
298
299

300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320











321
322
323
324
325
326
327
328
329
330
331
332
333
334

335
336
337



338
339
340
341

342
343
344


345
346
347


348
349
350

351
352
353
354
355
356
357
358
359
360
361
362
363


364
365
366
367
368
369

370
371



372
373
374
375
376
377
378
379

380
381
382
383


384
385
386
387

388
389
390
391
392
393
394
395
396
397
398
399
400


401
402
403
404

405
406
407
408
409
410
411
412
413
414
415


416
417
418
419
420
421
422
423
424







-
+




















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



-
+


-
-
-
+
+
+

-
+


-
-
+
+

-
-
+
+

-
+












-
-






-
+

-
-
-
+
+
+





-
+



-
-
+
+


-
+












-
-
+
+


-
+










-
-
+
+







	    TkWindow *topWin;

	    name = arg;
	    firstOption = 4;

	    /*
	     * Need to check if the _command_ that we are about to create is
	     * the name of the current master widget command (normally "." but
	     * the name of the current model widget command (normally "." but
	     * could have been renamed) and fail in that case before a really
	     * nasty and hard to stop crash happens.
	     */

	    topWin = (TkWindow *) TkToplevelWindowForCommand(interp, name);
	    if (topWin != NULL && winPtr->mainPtr->winPtr == topWin) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"images may not be named the same as the main window",
			-1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "SMASH_MAIN", NULL);
		return TCL_ERROR;
	    }
	}

	/*
	 * Create the data structure for the new image.
	 */

	hPtr = Tcl_CreateHashEntry(&winPtr->mainPtr->imageTable, name, &isNew);
	if (isNew) {
	    masterPtr = (ImageMaster *)ckalloc(sizeof(ImageMaster));
	    masterPtr->typePtr = NULL;
	    masterPtr->masterData = NULL;
	    masterPtr->width = masterPtr->height = 1;
	    masterPtr->tablePtr = &winPtr->mainPtr->imageTable;
	    masterPtr->hPtr = hPtr;
	    masterPtr->instancePtr = NULL;
	    masterPtr->deleted = 0;
	    masterPtr->winPtr = winPtr->mainPtr->winPtr;
	    Tcl_Preserve(masterPtr->winPtr);
	    Tcl_SetHashValue(hPtr, masterPtr);
	    modelPtr = (ImageModel *)ckalloc(sizeof(ImageModel));
	    modelPtr->typePtr = NULL;
	    modelPtr->modelData = NULL;
	    modelPtr->width = modelPtr->height = 1;
	    modelPtr->tablePtr = &winPtr->mainPtr->imageTable;
	    modelPtr->hPtr = hPtr;
	    modelPtr->instancePtr = NULL;
	    modelPtr->deleted = 0;
	    modelPtr->winPtr = winPtr->mainPtr->winPtr;
	    Tcl_Preserve(modelPtr->winPtr);
	    Tcl_SetHashValue(hPtr, modelPtr);
	} else {
	    /*
	     * An image already exists by this name. Disconnect the instances
	     * from the master.
	     * from the model.
	     */

	    masterPtr = (ImageMaster *)Tcl_GetHashValue(hPtr);
	    if (masterPtr->typePtr != NULL) {
		for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
	    modelPtr = (ImageModel *)Tcl_GetHashValue(hPtr);
	    if (modelPtr->typePtr != NULL) {
		for (imagePtr = modelPtr->instancePtr; imagePtr != NULL;
			imagePtr = imagePtr->nextPtr) {
		    masterPtr->typePtr->freeProc(imagePtr->instanceData,
		    modelPtr->typePtr->freeProc(imagePtr->instanceData,
			    imagePtr->display);
		    imagePtr->changeProc(imagePtr->widgetClientData, 0, 0,
			    masterPtr->width, masterPtr->height,
			    masterPtr->width, masterPtr->height);
			    modelPtr->width, modelPtr->height,
			    modelPtr->width, modelPtr->height);
		}
		masterPtr->typePtr->deleteProc(masterPtr->masterData);
		masterPtr->typePtr = NULL;
		modelPtr->typePtr->deleteProc(modelPtr->modelData);
		modelPtr->typePtr = NULL;
	    }
	    masterPtr->deleted = 0;
	    modelPtr->deleted = 0;
	}

	/*
	 * Call the image type manager so that it can perform its own
	 * initialization, then re-"get" for any existing instances of the
	 * image.
	 */

	objv += firstOption;
	objc -= firstOption;
	args = (Tcl_Obj **) objv;
	if (oldimage) {
	    int i;

	    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(masterPtr);
	Tcl_Preserve(modelPtr);
	if (typePtr->createProc(interp, name, objc, args, typePtr,
		(Tk_ImageMaster)masterPtr, &masterPtr->masterData) != TCL_OK){
	    EventuallyDeleteImage(masterPtr, 0);
	    Tcl_Release(masterPtr);
		(Tk_ImageModel)modelPtr, &modelPtr->modelData) != TCL_OK){
	    EventuallyDeleteImage(modelPtr, 0);
	    Tcl_Release(modelPtr);
	    if (oldimage) {
		ckfree(args);
	    }
	    return TCL_ERROR;
	}
	Tcl_Release(masterPtr);
	Tcl_Release(modelPtr);
	if (oldimage) {
	    ckfree(args);
	}
	masterPtr->typePtr = typePtr;
	for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
	modelPtr->typePtr = typePtr;
	for (imagePtr = modelPtr->instancePtr; imagePtr != NULL;
		imagePtr = imagePtr->nextPtr) {
	    imagePtr->instanceData = typePtr->getProc(imagePtr->tkwin,
		    masterPtr->masterData);
		    modelPtr->modelData);
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		(const char *)Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr), -1));
	break;
    }
    case IMAGE_DELETE:
	for (i = 2; i < objc; i++) {
	    arg = Tcl_GetString(objv[i]);
	    hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg);
	    if (hPtr == NULL) {
		goto alreadyDeleted;
	    }
	    masterPtr = (ImageMaster *)Tcl_GetHashValue(hPtr);
	    if (masterPtr->deleted) {
	    modelPtr = (ImageModel *)Tcl_GetHashValue(hPtr);
	    if (modelPtr->deleted) {
		goto alreadyDeleted;
	    }
	    DeleteImage(masterPtr);
	    DeleteImage(modelPtr);
	}
	break;
    case IMAGE_NAMES:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    return TCL_ERROR;
	}
	hPtr = Tcl_FirstHashEntry(&winPtr->mainPtr->imageTable, &search);
	resultObj = Tcl_NewObj();
	for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	    masterPtr = (ImageMaster *)Tcl_GetHashValue(hPtr);
	    if (masterPtr->deleted) {
	    modelPtr = (ImageModel *)Tcl_GetHashValue(hPtr);
	    if (modelPtr->deleted) {
		continue;
	    }
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    (const char *)Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr), -1));
	}
	Tcl_SetObjResult(interp, resultObj);
	break;
446
447
448
449
450
451
452
453

454
455
456
457
458
459
460
461
462
463
464
465
466
467
468


469
470
471
472
473
474
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
477
478

479
480
481

482
483

484
485
486
487

488
489
490
491
492
493
494
495







-
+













-
-
+
+









-
+



-
+


-
+

-
+



-
+








    case IMAGE_HEIGHT:
    case IMAGE_INUSE:
    case IMAGE_TYPE:
    case IMAGE_WIDTH:
	/*
	 * These operations all parse virtually identically. First check to
	 * see if three args are given. Then get a non-deleted master from the
	 * see if three args are given. Then get a non-deleted model from the
	 * third arg.
	 */

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "name");
	    return TCL_ERROR;
	}

	arg = Tcl_GetString(objv[2]);
	hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg);
	if (hPtr == NULL) {
	    goto alreadyDeleted;
	}
	masterPtr = (ImageMaster *)Tcl_GetHashValue(hPtr);
	if (masterPtr->deleted) {
	modelPtr = (ImageModel *)Tcl_GetHashValue(hPtr);
	if (modelPtr->deleted) {
	    goto alreadyDeleted;
	}

	/*
	 * Now we read off the specific piece of data we were asked for.
	 */

	switch ((enum options) index) {
	case IMAGE_HEIGHT:
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(masterPtr->height));
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(modelPtr->height));
	    break;
	case IMAGE_INUSE:
	    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
		    masterPtr->typePtr && masterPtr->instancePtr));
		    modelPtr->typePtr && modelPtr->instancePtr));
	    break;
	case IMAGE_TYPE:
	    if (masterPtr->typePtr != NULL) {
	    if (modelPtr->typePtr != NULL) {
		Tcl_SetObjResult(interp,
			Tcl_NewStringObj(masterPtr->typePtr->name, -1));
			Tcl_NewStringObj(modelPtr->typePtr->name, -1));
	    }
	    break;
	case IMAGE_WIDTH:
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(masterPtr->width));
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(modelPtr->width));
	    break;
	default:
	    Tcl_Panic("can't happen");
	}
	break;
    }
    return TCL_OK;
520
521
522
523
524
525
526
527

528
529
530
531
532
533
534
535
536
537
538

539
540
541
542
543



544
545
546
547
548
549
550
551
552
553
554
555

556
557
558
559

560
561
562
563
564
565
566
567
568
569

570
571

572
573

574
575
576

577
578
579
580
581
582
583
517
518
519
520
521
522
523

524
525
526
527
528
529
530
531
532
533
534

535
536
537



538
539
540
541
542
543
544
545
546
547
548
549
550
551

552
553
554
555

556
557
558
559
560
561
562
563
564
565

566
567

568
569

570
571
572

573
574
575
576
577
578
579
580







-
+










-
+


-
-
-
+
+
+











-
+



-
+









-
+

-
+

-
+


-
+







 *	redisplay themselves as appropriate.
 *
 *----------------------------------------------------------------------
 */

void
Tk_ImageChanged(
    Tk_ImageMaster imageMaster,	/* Image that needs redisplay. */
    Tk_ImageModel imageModel,	/* Image that needs redisplay. */
    int x, int y,		/* Coordinates of upper-left pixel of region
				 * of image that needs to be redrawn. */
    int width, int height,	/* Dimensions (in pixels) of region of image
				 * to redraw. If either dimension is zero then
				 * the image doesn't need to be redrawn
				 * (perhaps all that happened is that its size
				 * changed). */
    int imageWidth, int imageHeight)
				/* New dimensions of image. */
{
    ImageMaster *masterPtr = (ImageMaster *) imageMaster;
    ImageModel *modelPtr = (ImageModel *) imageModel;
    Image *imagePtr;

    masterPtr->width = imageWidth;
    masterPtr->height = imageHeight;
    for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
    modelPtr->width = imageWidth;
    modelPtr->height = imageHeight;
    for (imagePtr = modelPtr->instancePtr; imagePtr != NULL;
	    imagePtr = imagePtr->nextPtr) {
	imagePtr->changeProc(imagePtr->widgetClientData, x, y, width, height,
		imageWidth, imageHeight);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_NameOfImage --
 *
 *	Given a token for an image master, this function returns the name of
 *	Given a token for an image model, this function returns the name of
 *	the image.
 *
 * Results:
 *	The return value is the string name for imageMaster.
 *	The return value is the string name for imageModel.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

const char *
Tk_NameOfImage(
    Tk_ImageMaster imageMaster)	/* Token for image. */
    Tk_ImageModel imageModel)	/* Token for image. */
{
    ImageMaster *masterPtr = (ImageMaster *) imageMaster;
    ImageModel *modelPtr = (ImageModel *) imageModel;

    if (masterPtr->hPtr == NULL) {
    if (modelPtr->hPtr == NULL) {
	return NULL;
    }
    return (const char *)Tcl_GetHashKey(masterPtr->tablePtr, masterPtr->hPtr);
    return (const char *)Tcl_GetHashKey(modelPtr->tablePtr, modelPtr->hPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetImage --
 *
607
608
609
610
611
612
613
614

615
616
617
618
619
620
621
622


623
624
625

626
627
628
629
630
631

632
633

634
635
636
637


638
639
640
641
642
643
644
604
605
606
607
608
609
610

611
612
613
614
615
616
617


618
619
620
621

622
623
624
625
626
627

628
629

630
631
632


633
634
635
636
637
638
639
640
641







-
+






-
-
+
+


-
+





-
+

-
+


-
-
+
+







    const char *name,		/* Name of desired image. */
    Tk_ImageChangedProc *changeProc,
				/* Function to invoke when redisplay is needed
				 * because image's pixels or size changed. */
    ClientData clientData)	/* One-word argument to pass to damageProc. */
{
    Tcl_HashEntry *hPtr;
    ImageMaster *masterPtr;
    ImageModel *modelPtr;
    Image *imagePtr;

    hPtr = Tcl_FindHashEntry(&((TkWindow *) tkwin)->mainPtr->imageTable, name);
    if (hPtr == NULL) {
	goto noSuchImage;
    }
    masterPtr = (ImageMaster *)Tcl_GetHashValue(hPtr);
    if (masterPtr->typePtr == NULL) {
    modelPtr = (ImageModel *)Tcl_GetHashValue(hPtr);
    if (modelPtr->typePtr == NULL) {
	goto noSuchImage;
    }
    if (masterPtr->deleted) {
    if (modelPtr->deleted) {
	goto noSuchImage;
    }
    imagePtr = (Image *)ckalloc(sizeof(Image));
    imagePtr->tkwin = tkwin;
    imagePtr->display = Tk_Display(tkwin);
    imagePtr->masterPtr = masterPtr;
    imagePtr->modelPtr = modelPtr;
    imagePtr->instanceData =
	    masterPtr->typePtr->getProc(tkwin, masterPtr->masterData);
	    modelPtr->typePtr->getProc(tkwin, modelPtr->modelData);
    imagePtr->changeProc = changeProc;
    imagePtr->widgetClientData = clientData;
    imagePtr->nextPtr = masterPtr->instancePtr;
    masterPtr->instancePtr = imagePtr;
    imagePtr->nextPtr = modelPtr->instancePtr;
    modelPtr->instancePtr = imagePtr;
    return (Tk_Image) imagePtr;

  noSuchImage:
    if (interp) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"image \"%s\" doesn't exist", name));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "IMAGE", name, NULL);
666
667
668
669
670
671
672
673

674
675
676
677
678
679
680
681


682
683
684

685
686

687
688
689
690
691
692
693
694
695
696
697


698
699
700
701
702



703
704
705


706
707
708
709
710
711
712
663
664
665
666
667
668
669

670
671
672
673
674
675
676


677
678
679
680

681
682

683
684
685
686
687
688
689
690
691
692


693
694
695
696



697
698
699
700


701
702
703
704
705
706
707
708
709







-
+






-
-
+
+


-
+

-
+









-
-
+
+


-
-
-
+
+
+

-
-
+
+








void
Tk_FreeImage(
    Tk_Image image)		/* Token for image that is no longer needed by
				 * a widget. */
{
    Image *imagePtr = (Image *) image;
    ImageMaster *masterPtr = imagePtr->masterPtr;
    ImageModel *modelPtr = imagePtr->modelPtr;
    Image *prevPtr;

    /*
     * Clean up the particular instance.
     */

    if (masterPtr->typePtr != NULL) {
	masterPtr->typePtr->freeProc(imagePtr->instanceData,
    if (modelPtr->typePtr != NULL) {
	modelPtr->typePtr->freeProc(imagePtr->instanceData,
		imagePtr->display);
    }
    prevPtr = masterPtr->instancePtr;
    prevPtr = modelPtr->instancePtr;
    if (prevPtr == imagePtr) {
	masterPtr->instancePtr = imagePtr->nextPtr;
	modelPtr->instancePtr = imagePtr->nextPtr;
    } else {
	while (prevPtr->nextPtr != imagePtr) {
	    prevPtr = prevPtr->nextPtr;
	}
	prevPtr->nextPtr = imagePtr->nextPtr;
    }
    ckfree(imagePtr);

    /*
     * If there are no more instances left for the master, and if the master
     * image has been deleted, then delete the master too.
     * If there are no more instances left for the model, and if the model
     * image has been deleted, then delete the model too.
     */

    if ((masterPtr->typePtr == NULL) && (masterPtr->instancePtr == NULL)) {
	if (masterPtr->hPtr != NULL) {
	    Tcl_DeleteHashEntry(masterPtr->hPtr);
    if ((modelPtr->typePtr == NULL) && (modelPtr->instancePtr == NULL)) {
	if (modelPtr->hPtr != NULL) {
	    Tcl_DeleteHashEntry(modelPtr->hPtr);
	}
	Tcl_Release(masterPtr->winPtr);
	ckfree(masterPtr);
	Tcl_Release(modelPtr->winPtr);
	ckfree(modelPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PostscriptImage --
738
739
740
741
742
743
744
745

746
747

748
749
750
751
752
753
754
755
756
757
758
759
760



761
762
763
764
765
766
767
735
736
737
738
739
740
741

742
743

744
745
746
747
748
749
750
751
752
753
754



755
756
757
758
759
760
761
762
763
764







-
+

-
+










-
-
-
+
+
+







    Image *imagePtr = (Image *) image;
    int result;
    XImage *ximage;
    Pixmap pmap;
    GC newGC;
    XGCValues gcValues;

    if (imagePtr->masterPtr->typePtr == NULL) {
    if (imagePtr->modelPtr->typePtr == NULL) {
	/*
	 * No master for image, so nothing to display on postscript.
	 * No model for image, so nothing to display on postscript.
	 */

	return TCL_OK;
    }

    /*
     * Check if an image specific postscript-generation function exists;
     * otherwise go on with generic code.
     */

    if (imagePtr->masterPtr->typePtr->postscriptProc != NULL) {
	return imagePtr->masterPtr->typePtr->postscriptProc(
		imagePtr->masterPtr->masterData, interp, tkwin, psinfo,
    if (imagePtr->modelPtr->typePtr->postscriptProc != NULL) {
	return imagePtr->modelPtr->typePtr->postscriptProc(
		imagePtr->modelPtr->modelData, interp, tkwin, psinfo,
		x, y, width, height, prepass);
    }

    if (prepass) {
	return TCL_OK;
    }

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







-
+

-
+



















-
-
+
+

-
-
+
+

-
+







				 * the Tk_GetImage call for the image. */
    int drawableX, int drawableY)
				/* Coordinates in drawable that correspond to
				 * imageX and imageY. */
{
    Image *imagePtr = (Image *) image;

    if (imagePtr->masterPtr->typePtr == NULL) {
    if (imagePtr->modelPtr->typePtr == NULL) {
	/*
	 * No master for image, so nothing to display.
	 * No model for image, so nothing to display.
	 */

	return;
    }

    /*
     * Clip the redraw area to the area of the image.
     */

    if (imageX < 0) {
	width += imageX;
	drawableX -= imageX;
	imageX = 0;
    }
    if (imageY < 0) {
	height += imageY;
	drawableY -= imageY;
	imageY = 0;
    }
    if ((imageX + width) > imagePtr->masterPtr->width) {
	width = imagePtr->masterPtr->width - imageX;
    if ((imageX + width) > imagePtr->modelPtr->width) {
	width = imagePtr->modelPtr->width - imageX;
    }
    if ((imageY + height) > imagePtr->masterPtr->height) {
	height = imagePtr->masterPtr->height - imageY;
    if ((imageY + height) > imagePtr->modelPtr->height) {
	height = imagePtr->modelPtr->height - imageY;
    }
    imagePtr->masterPtr->typePtr->displayProc(imagePtr->instanceData,
    imagePtr->modelPtr->typePtr->displayProc(imagePtr->instanceData,
	    imagePtr->display, drawable, imageX, imageY, width, height,
	    drawableX, drawableY);
}

/*
 *----------------------------------------------------------------------
 *
892
893
894
895
896
897
898
899
900


901
902
903
904
905
906
907
889
890
891
892
893
894
895


896
897
898
899
900
901
902
903
904







-
-
+
+







Tk_SizeOfImage(
    Tk_Image image,		/* Token for image whose size is wanted. */
    int *widthPtr,		/* Return width of image here. */
    int *heightPtr)		/* Return height of image here. */
{
    Image *imagePtr = (Image *) image;

    *widthPtr = imagePtr->masterPtr->width;
    *heightPtr = imagePtr->masterPtr->height;
    *widthPtr = imagePtr->modelPtr->width;
    *heightPtr = imagePtr->modelPtr->height;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_DeleteImage --
 *
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
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







-
+














-
+







-
+




-
-
+
+

-
+



-
-
+
+

-
+

-
-
-
+
+
+

-
-
+
+

-
+







    if (winPtr == NULL) {
	return;
    }
    hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, name);
    if (hPtr == NULL) {
	return;
    }
    DeleteImage((ImageMaster *)Tcl_GetHashValue(hPtr));
    DeleteImage((ImageModel *)Tcl_GetHashValue(hPtr));
}

/*
 *----------------------------------------------------------------------
 *
 * DeleteImage --
 *
 *	This function is responsible for deleting an image.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The connection is dropped between instances of this image and an image
 *	master. Image instances will redisplay themselves as empty areas, but
 *	model. Image instances will redisplay themselves as empty areas, but
 *	existing instances will not be deleted.
 *
 *----------------------------------------------------------------------
 */

static void
DeleteImage(
    ImageMaster *masterPtr)	/* Pointer to main data structure for image. */
    ImageModel *modelPtr)	/* Pointer to main data structure for image. */
{
    Image *imagePtr;
    Tk_ImageType *typePtr;

    typePtr = masterPtr->typePtr;
    masterPtr->typePtr = NULL;
    typePtr = modelPtr->typePtr;
    modelPtr->typePtr = NULL;
    if (typePtr != NULL) {
	for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
	for (imagePtr = modelPtr->instancePtr; imagePtr != NULL;
		imagePtr = imagePtr->nextPtr) {
	    typePtr->freeProc(imagePtr->instanceData, imagePtr->display);
	    imagePtr->changeProc(imagePtr->widgetClientData, 0, 0,
		    masterPtr->width, masterPtr->height, masterPtr->width,
		    masterPtr->height);
		    modelPtr->width, modelPtr->height, modelPtr->width,
		    modelPtr->height);
	}
	typePtr->deleteProc(masterPtr->masterData);
	typePtr->deleteProc(modelPtr->modelData);
    }
    if (masterPtr->instancePtr == NULL) {
	if (masterPtr->hPtr != NULL) {
	    Tcl_DeleteHashEntry(masterPtr->hPtr);
    if (modelPtr->instancePtr == NULL) {
	if (modelPtr->hPtr != NULL) {
	    Tcl_DeleteHashEntry(modelPtr->hPtr);
	}
	Tcl_Release(masterPtr->winPtr);
	ckfree(masterPtr);
	Tcl_Release(modelPtr->winPtr);
	ckfree(modelPtr);
    } else {
	masterPtr->deleted = 1;
	modelPtr->deleted = 1;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * EventuallyDeleteImage --
1001
1002
1003
1004
1005
1006
1007
1008

1009
1010
1011
1012
1013

1014
1015
1016
1017



1018
1019
1020
1021
1022
1023
1024
998
999
1000
1001
1002
1003
1004

1005
1006
1007
1008
1009

1010
1011



1012
1013
1014
1015
1016
1017
1018
1019
1020
1021







-
+




-
+

-
-
-
+
+
+







 *	ill effects.
 *
 *----------------------------------------------------------------------
 */

static void
EventuallyDeleteImage(
    ImageMaster *masterPtr,	/* Pointer to main data structure for image. */
    ImageModel *modelPtr,	/* Pointer to main data structure for image. */
    int forgetImageHashNow)	/* Flag to say whether the hash table is about
				 * to vanish. */
{
    if (forgetImageHashNow) {
	masterPtr->hPtr = NULL;
	modelPtr->hPtr = NULL;
    }
    if (!masterPtr->deleted) {
	masterPtr->deleted = 1;
	Tcl_EventuallyFree(masterPtr, (Tcl_FreeProc *) DeleteImage);
    if (!modelPtr->deleted) {
	modelPtr->deleted = 1;
	Tcl_EventuallyFree(modelPtr, (Tcl_FreeProc *) DeleteImage);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkDeleteAllImages --
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
1039
1040
1041
1042
1043
1044
1045

1046
1047
1048
1049
1050
1051
1052
1053

1054
1055
1056

1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071

1072
1073
1074
1075
1076
1077
1078
1079
1080
1081

1082
1083
1084
1085
1086
1087
1088


1089
1090
1091
1092
1093


1094
1095
1096
1097
1098
1099
1100
1101
1102







-
+







-
+


-
+














-
+









-
+






-
-
+
+



-
-
+
+







				 * going away. */
{
    Tcl_HashSearch search;
    Tcl_HashEntry *hPtr;

    for (hPtr = Tcl_FirstHashEntry(&mainPtr->imageTable, &search);
	    hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	EventuallyDeleteImage((ImageMaster *)Tcl_GetHashValue(hPtr), 1);
	EventuallyDeleteImage((ImageModel *)Tcl_GetHashValue(hPtr), 1);
    }
    Tcl_DeleteHashTable(&mainPtr->imageTable);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetImageMasterData --
 * Tk_GetImageModelData --
 *
 *	Given the name of an image, this function returns the type of the
 *	image and the clientData associated with its master.
 *	image and the clientData associated with its model.
 *
 * Results:
 *	If there is no image by the given name, then NULL is returned and a
 *	NULL value is stored at *typePtrPtr. Otherwise the return value is the
 *	clientData returned by the createProc when the image was created and a
 *	pointer to the type structure for the image is stored at *typePtrPtr.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

ClientData
Tk_GetImageMasterData(
Tk_GetImageModelData(
    Tcl_Interp *interp,		/* Interpreter in which the image was
				 * created. */
    const char *name,		/* Name of image. */
    const Tk_ImageType **typePtrPtr)
				/* Points to location to fill in with pointer
				 * to type information for image. */
{
    TkWindow *winPtr = (TkWindow *) Tk_MainWindow(interp);
    Tcl_HashEntry *hPtr;
    ImageMaster *masterPtr;
    ImageModel *modelPtr;

    hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, name);
    if (hPtr == NULL) {
	*typePtrPtr = NULL;
	return NULL;
    }
    masterPtr = (ImageMaster *)Tcl_GetHashValue(hPtr);
    if (masterPtr->deleted) {
    modelPtr = (ImageModel *)Tcl_GetHashValue(hPtr);
    if (modelPtr->deleted) {
	*typePtrPtr = NULL;
	return NULL;
    }
    *typePtrPtr = masterPtr->typePtr;
    return masterPtr->masterData;
    *typePtrPtr = modelPtr->typePtr;
    return modelPtr->modelData;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_SetTSOrigin --
 *

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
60
61
62
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





-
-
-
+
+
+








-
+



-
-
+
+




















-
-
+
+









-
+













-
+










-
+







/*
 * 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 © 1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 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 master for a bitmap
 * The following data structure represents the model for a bitmap
 * image:
 */

typedef struct BitmapMaster {
    Tk_ImageMaster tkMaster;	/* Tk's token for image master. NULL means the
typedef struct {
    Tk_ImageModel tkModel;	/* Tk's token for image model. NULL means the
				 * image is being deleted. */
    Tcl_Interp *interp;		/* Interpreter for application that is using
				 * image. */
    Tcl_Command imageCmd;	/* Token for image command (used to delete it
				 * when the image goes away). NULL means the
				 * image command has already been deleted. */
    int width, height;		/* Dimensions of image. */
    char *data;			/* Data comprising bitmap (suitable for input
				 * to XCreateBitmapFromData). May be NULL if
				 * no data. Malloc'ed. */
    char *maskData;		/* Data for bitmap's mask (suitable for input
				 * to XCreateBitmapFromData). Malloc'ed. */
    Tk_Uid fgUid;		/* Value of -foreground option (malloc'ed). */
    Tk_Uid bgUid;		/* Value of -background option (malloc'ed). */
    char *fileString;		/* Value of -file option (malloc'ed). */
    char *dataString;		/* Value of -data option (malloc'ed). */
    char *maskFileString;	/* Value of -maskfile option (malloc'ed). */
    char *maskDataString;	/* Value of -maskdata option (malloc'ed). */
    struct BitmapInstance *instancePtr;
				/* First in list of all instances associated
				 * with this master. */
} BitmapMaster;
				 * with this model. */
} BitmapModel;

/*
 * The following data structure represents all of the instances of an image
 * that lie within a particular window:
 */

typedef struct BitmapInstance {
    size_t refCount;		/* Number of instances that share this data
				 * structure. */
    BitmapMaster *masterPtr;	/* Pointer to master for image. */
    BitmapModel *modelPtr;	/* Pointer to model for image. */
    Tk_Window tkwin;		/* Window in which the instances will be
				 * displayed. */
    XColor *fg;			/* Foreground color for displaying image. */
    XColor *bg;			/* Background color for displaying image. */
    Pixmap bitmap;		/* The bitmap to display. */
    Pixmap mask;		/* Mask: only display bitmap pixels where
				 * there are 1's here. */
    GC gc;			/* Graphics context for displaying bitmap.
				 * None means there was an error while setting
				 * up the instance, so it cannot be
				 * displayed. */
    struct BitmapInstance *nextPtr;
				/* Next in list of all instance structures
				 * associated with masterPtr (NULL means end
				 * associated with modelPtr (NULL means end
				 * of list). */
} BitmapInstance;

/*
 * The type record for bitmap images:
 */

static int		GetByte(Tcl_Channel chan);
static int		ImgBmapCreate(Tcl_Interp *interp,
			    const char *name, int argc, Tcl_Obj *const objv[],
			    const Tk_ImageType *typePtr, Tk_ImageMaster master,
			    const Tk_ImageType *typePtr, Tk_ImageModel model,
			    ClientData *clientDataPtr);
static ClientData	ImgBmapGet(Tk_Window tkwin, ClientData clientData);
static void		ImgBmapDisplay(ClientData clientData,
			    Display *display, Drawable drawable,
			    int imageX, int imageY, int width, int height,
			    int drawableX, int drawableY);
static void		ImgBmapFree(ClientData clientData, Display *display);
104
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(BitmapMaster, bgUid), 0, NULL},
	"", offsetof(BitmapModel, bgUid), 0, NULL},
    {TK_CONFIG_STRING, "-data", NULL, NULL,
	NULL, offsetof(BitmapMaster, dataString), TK_CONFIG_NULL_OK, NULL},
	NULL, offsetof(BitmapModel, dataString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_STRING, "-file", NULL, NULL,
	NULL, offsetof(BitmapMaster, fileString), TK_CONFIG_NULL_OK, NULL},
	NULL, offsetof(BitmapModel, fileString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_UID, "-foreground", NULL, NULL,
	"#000000", offsetof(BitmapMaster, fgUid), 0, NULL},
	"#000000", offsetof(BitmapModel, fgUid), 0, NULL},
    {TK_CONFIG_STRING, "-maskdata", NULL, NULL,
	NULL, offsetof(BitmapMaster, maskDataString), TK_CONFIG_NULL_OK, NULL},
	NULL, offsetof(BitmapModel, maskDataString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_STRING, "-maskfile", NULL, NULL,
	NULL, offsetof(BitmapMaster, maskFileString), TK_CONFIG_NULL_OK, NULL},
	NULL, offsetof(BitmapModel, maskFileString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * The following data structure is used to describe the state of parsing a
 * bitmap file or string. It is used for communication between TkGetBitmapData
 * and NextBitmapWord.
145
146
147
148
149
150
151
152

153
154
155
156
157
158
159
145
146
147
148
149
150
151

152
153
154
155
156
157
158
159







-
+







 * Prototypes for procedures used only locally in this file:
 */

static int		ImgBmapCmd(ClientData clientData, Tcl_Interp *interp,
			    int argc, Tcl_Obj *const objv[]);
static void		ImgBmapCmdDeletedProc(ClientData clientData);
static void		ImgBmapConfigureInstance(BitmapInstance *instancePtr);
static int		ImgBmapConfigureMaster(BitmapMaster *masterPtr,
static int		ImgBmapConfigureModel(BitmapModel *modelPtr,
			    int argc, Tcl_Obj *const objv[], int flags);
static int		NextBitmapWord(ParseInfo *parseInfoPtr);

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapCreate --
174
175
176
177
178
179
180
181

182
183
184
185
186

187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
















205
206
207

208
209
210
211
212
213
214

215
216
217
218
219
220
221
222

223
224
225
226
227
228
229
230
231
232
233


234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250


251
252
253
254
255
256
257
258
259
260
261
262
263



264
265
266
267
268
269





270
271
272
273
274
275



276
277
278
279
280




281
282

283
284
285
286
287


288
289

290
291
292
293
294
295
296





297
298

299
300
301
302
303
304
305
306
307
308
309
310

311
312
313
314
315


316
317
318
319
320
321
322
323
324
325
326


327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343

344
345
346
347
348
349
350
351

352
353
354
355
356
357



358
359
360
361
362
363
364
365
366
367
368
369
370


371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391

392
393
394
395
396


397
398

399
400
401
402
403


404
405
406
407
408
409
410
411
412
413

414
415
416
417
418
419
420
174
175
176
177
178
179
180

181
182
183
184
185

186
187
188
















189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206

207
208
209
210
211
212
213

214
215
216
217
218
219
220
221

222
223
224
225
226
227
228
229
230
231


232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248


249
250
251
252
253
254
255
256
257
258
259
260



261
262
263
264





265
266
267
268
269
270
271
272



273
274
275
276




277
278
279
280
281

282
283
284
285


286
287
288

289
290
291





292
293
294
295
296
297

298
299
300
301
302
303
304
305
306
307
308
309

310
311
312
313


314
315
316
317
318
319
320
321
322
323
324


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

343
344
345
346
347
348
349
350

351
352
353
354



355
356
357
358
359
360
361
362
363
364
365
366
367
368


369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390

391
392
393
394


395
396
397

398
399
400
401


402
403
404
405
406
407
408
409
410
411
412

413
414
415
416
417
418
419
420







-
+




-
+


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


-
+






-
+







-
+









-
-
+
+















-
-
+
+










-
-
-
+
+
+

-
-
-
-
-
+
+
+
+
+



-
-
-
+
+
+

-
-
-
-
+
+
+
+

-
+



-
-
+
+

-
+


-
-
-
-
-
+
+
+
+
+

-
+











-
+



-
-
+
+









-
-
+
+
















-
+







-
+



-
-
-
+
+
+











-
-
+
+




















-
+



-
-
+
+

-
+



-
-
+
+









-
+







    Tcl_Interp *interp,		/* Interpreter for application containing
				 * image. */
    const char *name,			/* Name to use for image. */
    int argc,			/* Number of arguments. */
    Tcl_Obj *const argv[],	/* Argument objects for options (doesn't
				 * include image name or type). */
    const Tk_ImageType *typePtr,/* Pointer to our type record (not used). */
    Tk_ImageMaster master,	/* Token for image, to be used by us in later
    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. */
{
    BitmapMaster *masterPtr = (BitmapMaster *)ckalloc(sizeof(BitmapMaster));
    BitmapModel *modelPtr = (BitmapModel *)ckalloc(sizeof(BitmapModel));
    (void)typePtr;

    masterPtr->tkMaster = master;
    masterPtr->interp = interp;
    masterPtr->imageCmd = Tcl_CreateObjCommand(interp, name, ImgBmapCmd,
	    masterPtr, ImgBmapCmdDeletedProc);
    masterPtr->width = masterPtr->height = 0;
    masterPtr->data = NULL;
    masterPtr->maskData = NULL;
    masterPtr->fgUid = NULL;
    masterPtr->bgUid = NULL;
    masterPtr->fileString = NULL;
    masterPtr->dataString = NULL;
    masterPtr->maskFileString = NULL;
    masterPtr->maskDataString = NULL;
    masterPtr->instancePtr = NULL;
    if (ImgBmapConfigureMaster(masterPtr, argc, argv, 0) != TCL_OK) {
	ImgBmapDelete(masterPtr);
    modelPtr->tkModel = model;
    modelPtr->interp = interp;
    modelPtr->imageCmd = Tcl_CreateObjCommand(interp, name, ImgBmapCmd,
	    modelPtr, ImgBmapCmdDeletedProc);
    modelPtr->width = modelPtr->height = 0;
    modelPtr->data = NULL;
    modelPtr->maskData = NULL;
    modelPtr->fgUid = NULL;
    modelPtr->bgUid = NULL;
    modelPtr->fileString = NULL;
    modelPtr->dataString = NULL;
    modelPtr->maskFileString = NULL;
    modelPtr->maskDataString = NULL;
    modelPtr->instancePtr = NULL;
    if (ImgBmapConfigureModel(modelPtr, argc, argv, 0) != TCL_OK) {
	ImgBmapDelete(modelPtr);
	return TCL_ERROR;
    }
    *clientDataPtr = masterPtr;
    *clientDataPtr = modelPtr;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapConfigureMaster --
 * ImgBmapConfigureModel --
 *
 *	This procedure is called when a bitmap image is created or
 *	reconfigured. It process configuration options and resets any
 *	instances of the image.
 *
 * Results:
 *	A standard Tcl return value. If TCL_ERROR is returned then an error
 *	message is left in the masterPtr->interp's result.
 *	message is left in the modelPtr->interp's result.
 *
 * Side effects:
 *	Existing instances of the image will be redisplayed to match the new
 *	configuration options.
 *
 *----------------------------------------------------------------------
 */

static int
ImgBmapConfigureMaster(
    BitmapMaster *masterPtr,	/* Pointer to data structure describing
ImgBmapConfigureModel(
    BitmapModel *modelPtr,	/* Pointer to data structure describing
				 * overall bitmap image to (reconfigure). */
    int objc,			/* Number of entries in objv. */
    Tcl_Obj *const objv[],	/* Pairs of configuration options for image. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget, such
				 * as TK_CONFIG_ARGV_ONLY. */
{
    BitmapInstance *instancePtr;
    int maskWidth, maskHeight, dummy1, dummy2;
    const char **argv = (const char **)ckalloc((objc+1) * sizeof(char *));

    for (dummy1 = 0; dummy1 < objc; dummy1++) {
	argv[dummy1] = Tcl_GetString(objv[dummy1]);
    }
    argv[objc] = NULL;

    if (Tk_ConfigureWidget(masterPtr->interp, Tk_MainWindow(masterPtr->interp),
	    configSpecs, objc, argv, (char *) masterPtr, flags) != TCL_OK) {
    if (Tk_ConfigureWidget(modelPtr->interp, Tk_MainWindow(modelPtr->interp),
	    configSpecs, objc, argv, (char *) modelPtr, flags) != TCL_OK) {
	ckfree(argv);
	return TCL_ERROR;
    }
    ckfree(argv);

    /*
     * Parse the bitmap and/or mask to create binary data. Make sure that the
     * bitmap and mask have the same dimensions.
     */

    if (masterPtr->data != NULL) {
	ckfree(masterPtr->data);
	masterPtr->data = NULL;
    if (modelPtr->data != NULL) {
	ckfree(modelPtr->data);
	modelPtr->data = NULL;
    }
    if ((masterPtr->fileString != NULL) || (masterPtr->dataString != NULL)) {
	masterPtr->data = TkGetBitmapData(masterPtr->interp,
		masterPtr->dataString, masterPtr->fileString,
		&masterPtr->width, &masterPtr->height, &dummy1, &dummy2);
	if (masterPtr->data == NULL) {
    if ((modelPtr->fileString != NULL) || (modelPtr->dataString != NULL)) {
	modelPtr->data = TkGetBitmapData(modelPtr->interp,
		modelPtr->dataString, modelPtr->fileString,
		&modelPtr->width, &modelPtr->height, &dummy1, &dummy2);
	if (modelPtr->data == NULL) {
	    return TCL_ERROR;
	}
    }
    if (masterPtr->maskData != NULL) {
	ckfree(masterPtr->maskData);
	masterPtr->maskData = NULL;
    if (modelPtr->maskData != NULL) {
	ckfree(modelPtr->maskData);
	modelPtr->maskData = NULL;
    }
    if ((masterPtr->maskFileString != NULL)
	    || (masterPtr->maskDataString != NULL)) {
	if (masterPtr->data == NULL) {
	    Tcl_SetObjResult(masterPtr->interp, Tcl_NewStringObj(
    if ((modelPtr->maskFileString != NULL)
	    || (modelPtr->maskDataString != NULL)) {
	if (modelPtr->data == NULL) {
	    Tcl_SetObjResult(modelPtr->interp, Tcl_NewStringObj(
		    "can't have mask without bitmap", -1));
	    Tcl_SetErrorCode(masterPtr->interp, "TK", "IMAGE", "BITMAP",
	    Tcl_SetErrorCode(modelPtr->interp, "TK", "IMAGE", "BITMAP",
		    "NO_BITMAP", NULL);
	    return TCL_ERROR;
	}
	masterPtr->maskData = TkGetBitmapData(masterPtr->interp,
		masterPtr->maskDataString, masterPtr->maskFileString,
	modelPtr->maskData = TkGetBitmapData(modelPtr->interp,
		modelPtr->maskDataString, modelPtr->maskFileString,
		&maskWidth, &maskHeight, &dummy1, &dummy2);
	if (masterPtr->maskData == NULL) {
	if (modelPtr->maskData == NULL) {
	    return TCL_ERROR;
	}
	if ((maskWidth != masterPtr->width)
		|| (maskHeight != masterPtr->height)) {
	    ckfree(masterPtr->maskData);
	    masterPtr->maskData = NULL;
	    Tcl_SetObjResult(masterPtr->interp, Tcl_NewStringObj(
	if ((maskWidth != modelPtr->width)
		|| (maskHeight != modelPtr->height)) {
	    ckfree(modelPtr->maskData);
	    modelPtr->maskData = NULL;
	    Tcl_SetObjResult(modelPtr->interp, Tcl_NewStringObj(
		    "bitmap and mask have different sizes", -1));
	    Tcl_SetErrorCode(masterPtr->interp, "TK", "IMAGE", "BITMAP",
	    Tcl_SetErrorCode(modelPtr->interp, "TK", "IMAGE", "BITMAP",
		    "MASK_SIZE", NULL);
	    return TCL_ERROR;
	}
    }

    /*
     * Cycle through all of the instances of this image, regenerating the
     * information for each instance. Then force the image to be redisplayed
     * everywhere that it is used.
     */

    for (instancePtr = masterPtr->instancePtr; instancePtr != NULL;
    for (instancePtr = modelPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	ImgBmapConfigureInstance(instancePtr);
    }
    Tk_ImageChanged(masterPtr->tkMaster, 0, 0, masterPtr->width,
	    masterPtr->height, masterPtr->width, masterPtr->height);
    Tk_ImageChanged(modelPtr->tkModel, 0, 0, modelPtr->width,
	    modelPtr->height, modelPtr->width, modelPtr->height);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapConfigureInstance --
 *
 *	This procedure is called to create displaying information for a bitmap
 *	image instance based on the configuration information in the master.
 *	It is invoked both when new instances are created and when the master
 *	image instance based on the configuration information in the model.
 *	It is invoked both when new instances are created and when the model
 *	is reconfigured.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Generates errors via Tcl_BackgroundException if there are problems in
 *	setting up the instance.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapConfigureInstance(
    BitmapInstance *instancePtr)/* Instance to reconfigure. */
{
    BitmapMaster *masterPtr = instancePtr->masterPtr;
    BitmapModel *modelPtr = instancePtr->modelPtr;
    XColor *colorPtr;
    XGCValues gcValues;
    GC gc;
    unsigned int mask;
    Pixmap oldBitmap, oldMask;

    /*
     * For each of the options in masterPtr, translate the string form into an
     * For each of the options in modelPtr, translate the string form into an
     * internal form appropriate for instancePtr.
     */

    if (*masterPtr->bgUid != 0) {
	colorPtr = Tk_GetColor(masterPtr->interp, instancePtr->tkwin,
		masterPtr->bgUid);
    if (*modelPtr->bgUid != 0) {
	colorPtr = Tk_GetColor(modelPtr->interp, instancePtr->tkwin,
		modelPtr->bgUid);
	if (colorPtr == NULL) {
	    goto error;
	}
    } else {
	colorPtr = NULL;
    }
    if (instancePtr->bg != NULL) {
	Tk_FreeColor(instancePtr->bg);
    }
    instancePtr->bg = colorPtr;

    colorPtr = Tk_GetColor(masterPtr->interp, instancePtr->tkwin,
	    masterPtr->fgUid);
    colorPtr = Tk_GetColor(modelPtr->interp, instancePtr->tkwin,
	    modelPtr->fgUid);
    if (colorPtr == NULL) {
	goto error;
    }
    if (instancePtr->fg != NULL) {
	Tk_FreeColor(instancePtr->fg);
    }
    instancePtr->fg = colorPtr;

    /*
     * Careful: We have to allocate new Pixmaps before deleting the old ones.
     * Otherwise, The XID allocator will always return the same XID for the
     * new Pixmaps as was used for the old Pixmaps. And that will prevent the
     * data and/or mask from changing in the GC below.
     */

    oldBitmap = instancePtr->bitmap;
    instancePtr->bitmap = None;
    oldMask = instancePtr->mask;
    instancePtr->mask = None;

    if (masterPtr->data != NULL) {
    if (modelPtr->data != NULL) {
	instancePtr->bitmap = XCreateBitmapFromData(
		Tk_Display(instancePtr->tkwin),
		RootWindowOfScreen(Tk_Screen(instancePtr->tkwin)),
		masterPtr->data, (unsigned) masterPtr->width,
		(unsigned) masterPtr->height);
		modelPtr->data, (unsigned) modelPtr->width,
		(unsigned) modelPtr->height);
    }
    if (masterPtr->maskData != NULL) {
    if (modelPtr->maskData != NULL) {
	instancePtr->mask = XCreateBitmapFromData(
		Tk_Display(instancePtr->tkwin),
		RootWindowOfScreen(Tk_Screen(instancePtr->tkwin)),
		masterPtr->maskData, (unsigned) masterPtr->width,
		(unsigned) masterPtr->height);
		modelPtr->maskData, (unsigned) modelPtr->width,
		(unsigned) modelPtr->height);
    }

    if (oldMask != None) {
	Tk_FreePixmap(Tk_Display(instancePtr->tkwin), oldMask);
    }
    if (oldBitmap != None) {
	Tk_FreePixmap(Tk_Display(instancePtr->tkwin), oldBitmap);
    }

    if (masterPtr->data != NULL) {
    if (modelPtr->data != NULL) {
	gcValues.foreground = instancePtr->fg->pixel;
	gcValues.graphics_exposures = False;
	mask = GCForeground|GCGraphicsExposures;
	if (instancePtr->bg != NULL) {
	    gcValues.background = instancePtr->bg->pixel;
	    mask |= GCBackground;
	    if (instancePtr->mask != None) {
441
442
443
444
445
446
447
448

449
450
451


452
453
454
455
456
457
458
441
442
443
444
445
446
447

448
449


450
451
452
453
454
455
456
457
458







-
+

-
-
+
+







     * it clear that this instance cannot be displayed. Then report the error.
     */

    if (instancePtr->gc != NULL) {
	Tk_FreeGC(Tk_Display(instancePtr->tkwin), instancePtr->gc);
    }
    instancePtr->gc = NULL;
    Tcl_AppendObjToErrorInfo(masterPtr->interp, Tcl_ObjPrintf(
    Tcl_AppendObjToErrorInfo(modelPtr->interp, Tcl_ObjPrintf(
	    "\n    (while configuring image \"%s\")", Tk_NameOfImage(
	    masterPtr->tkMaster)));
    Tcl_BackgroundException(masterPtr->interp, TCL_ERROR);
	    modelPtr->tkModel)));
    Tcl_BackgroundException(modelPtr->interp, TCL_ERROR);
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetBitmapData --
 *
747
748
749
750
751
752
753
754

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
747
748
749
750
751
752
753

754
755
756
757
758
759

760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777

778
779
780
781

782
783
784

785
786
787

788
789
790
791
792
793
794
795







-
+





-
+

















-
+



-
+


-
+


-
+







 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
ImgBmapCmd(
    ClientData clientData,	/* Information about the image master. */
    ClientData clientData,	/* Information about the image model. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const bmapOptions[] = {"cget", "configure", NULL};
    BitmapMaster *masterPtr = (BitmapMaster *)clientData;
    BitmapModel *modelPtr = (BitmapModel *)clientData;
    int index;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObjStruct(interp, objv[1], bmapOptions,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
    switch (index) {
    case 0: /* cget */
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    return TCL_ERROR;
	}
	return Tk_ConfigureValue(interp, Tk_MainWindow(interp), configSpecs,
		(char *) masterPtr, 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 *) masterPtr, NULL, 0);
		    configSpecs, (char *) modelPtr, NULL, 0);
	} else if (objc == 3) {
	    return Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
		    configSpecs, (char *) masterPtr,
		    configSpecs, (char *) modelPtr,
		    Tcl_GetString(objv[2]), 0);
	} else {
	    return ImgBmapConfigureMaster(masterPtr, objc-2, objv+2,
	    return ImgBmapConfigureModel(modelPtr, objc-2, objv+2,
		    TK_CONFIG_ARGV_ONLY);
	}
    default:
	Tcl_Panic("bad const entries to bmapOptions in ImgBmapCmd");
	return TCL_OK;
    }
}
812
813
814
815
816
817
818
819

820
821
822

823
824
825
826
827
828
829
830

831
832
833
834
835
836
837
838
839
840
841
842
843
844
845

846
847
848
849
850
851
852
853


854
855
856
857
858
859
860
861
862


863
864
865
866
867
868
869
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







-
+


-
+







-
+














-
+






-
-
+
+







-
-
+
+







 *----------------------------------------------------------------------
 */

static ClientData
ImgBmapGet(
    Tk_Window tkwin,		/* Window in which the instance will be
				 * used. */
    ClientData masterData)	/* Pointer to our master structure for the
    ClientData modelData)	/* Pointer to our model structure for the
				 * image. */
{
    BitmapMaster *masterPtr = (BitmapMaster *)masterData;
    BitmapModel *modelPtr = (BitmapModel *)modelData;
    BitmapInstance *instancePtr;

    /*
     * See if there is already an instance for this window. If so then just
     * re-use it.
     */

    for (instancePtr = masterPtr->instancePtr; instancePtr != NULL;
    for (instancePtr = modelPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	if (instancePtr->tkwin == tkwin) {
	    instancePtr->refCount++;
	    return instancePtr;
	}
    }

    /*
     * The image isn't already in use in this window. Make a new instance of
     * the image.
     */

    instancePtr = (BitmapInstance *)ckalloc(sizeof(BitmapInstance));
    instancePtr->refCount = 1;
    instancePtr->masterPtr = masterPtr;
    instancePtr->modelPtr = modelPtr;
    instancePtr->tkwin = tkwin;
    instancePtr->fg = NULL;
    instancePtr->bg = NULL;
    instancePtr->bitmap = None;
    instancePtr->mask = None;
    instancePtr->gc = NULL;
    instancePtr->nextPtr = masterPtr->instancePtr;
    masterPtr->instancePtr = instancePtr;
    instancePtr->nextPtr = modelPtr->instancePtr;
    modelPtr->instancePtr = instancePtr;
    ImgBmapConfigureInstance(instancePtr);

    /*
     * If this is the first instance, must set the size of the image.
     */

    if (instancePtr->nextPtr == NULL) {
	Tk_ImageChanged(masterPtr->tkMaster, 0, 0, 0, 0, masterPtr->width,
		masterPtr->height);
	Tk_ImageChanged(modelPtr->tkModel, 0, 0, 0, 0, modelPtr->width,
		modelPtr->height);
    }

    return instancePtr;
}

/*
 *----------------------------------------------------------------------
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
971
972
973
974
975
976
977


978
979
980

981
982
983
984
985
986
987
988
989
990
991
992
993
994

995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008

1009
1010
1011

1012
1013

1014
1015
1016



1017
1018
1019
1020


1021
1022
1023


1024
1025
1026


1027
1028
1029
1030
1031
1032
1033
1034
1035







-
-
+
+

-
+













-
+













-
+


-
+

-
+


-
-
-
+
+
+

-
-
+
+

-
-
+
+

-
-
+
+







    }
    if (instancePtr->mask != None) {
	Tk_FreePixmap(display, instancePtr->mask);
    }
    if (instancePtr->gc != NULL) {
	Tk_FreeGC(display, instancePtr->gc);
    }
    if (instancePtr->masterPtr->instancePtr == instancePtr) {
	instancePtr->masterPtr->instancePtr = instancePtr->nextPtr;
    if (instancePtr->modelPtr->instancePtr == instancePtr) {
	instancePtr->modelPtr->instancePtr = instancePtr->nextPtr;
    } else {
	for (prevPtr = instancePtr->masterPtr->instancePtr;
	for (prevPtr = instancePtr->modelPtr->instancePtr;
		prevPtr->nextPtr != instancePtr; prevPtr = prevPtr->nextPtr) {
	    /* Empty loop body */
	}
	prevPtr->nextPtr = instancePtr->nextPtr;
    }
    ckfree(instancePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapDelete --
 *
 *	This procedure is called by the image code to delete the master
 *	This procedure is called by the image code to delete the model
 *	structure for an image.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Resources associated with the image get freed.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapDelete(
    ClientData masterData)	/* Pointer to BitmapMaster structure for
    ClientData modelData)	/* Pointer to BitmapModel structure for
				 * image. Must not have any more instances. */
{
    BitmapMaster *masterPtr = (BitmapMaster *)masterData;
    BitmapModel *modelPtr = (BitmapModel *)modelData;

    if (masterPtr->instancePtr != NULL) {
    if (modelPtr->instancePtr != NULL) {
	Tcl_Panic("tried to delete bitmap image when instances still exist");
    }
    masterPtr->tkMaster = NULL;
    if (masterPtr->imageCmd != NULL) {
	Tcl_DeleteCommandFromToken(masterPtr->interp, masterPtr->imageCmd);
    modelPtr->tkModel = NULL;
    if (modelPtr->imageCmd != NULL) {
	Tcl_DeleteCommandFromToken(modelPtr->interp, modelPtr->imageCmd);
    }
    if (masterPtr->data != NULL) {
	ckfree(masterPtr->data);
    if (modelPtr->data != NULL) {
	ckfree(modelPtr->data);
    }
    if (masterPtr->maskData != NULL) {
	ckfree(masterPtr->maskData);
    if (modelPtr->maskData != NULL) {
	ckfree(modelPtr->maskData);
    }
    Tk_FreeOptions(configSpecs, (char *) masterPtr, NULL, 0);
    ckfree(masterPtr);
    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



1058
1059
1060
1061
1062
1063
1064
1043
1044
1045
1046
1047
1048
1049

1050
1051
1052

1053
1054



1055
1056
1057
1058
1059
1060
1061
1062
1063
1064







-
+


-
+

-
-
-
+
+
+







 *	The image is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapCmdDeletedProc(
    ClientData clientData)	/* Pointer to BitmapMaster structure for
    ClientData clientData)	/* Pointer to BitmapModel structure for
				 * image. */
{
    BitmapMaster *masterPtr = (BitmapMaster *)clientData;
    BitmapModel *modelPtr = (BitmapModel *)clientData;

    masterPtr->imageCmd = NULL;
    if (masterPtr->tkMaster != NULL) {
	Tk_DeleteImage(masterPtr->interp, Tk_NameOfImage(masterPtr->tkMaster));
    modelPtr->imageCmd = NULL;
    if (modelPtr->tkModel != NULL) {
	Tk_DeleteImage(modelPtr->interp, Tk_NameOfImage(modelPtr->tkModel));
    }
}

/*
 *----------------------------------------------------------------------
 *
 * GetByte --
1078
1079
1080
1081
1082
1083
1084
1085

1086
1087
1088
1089
1090
1091
1092
1078
1079
1080
1081
1082
1083
1084

1085
1086
1087
1088
1089
1090
1091
1092







-
+







GetByte(
    Tcl_Channel chan)	/* The channel we read from. */
{
    char buffer;
    size_t size;

    size = Tcl_Read(chan, &buffer, 1);
    if ((size + 1) < 2) {
    if (size != 1) {
	return EOF;
    } else {
	return buffer;
    }
}

/*
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
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







-
+











-
+









-
+







    ClientData clientData,
    Tcl_Interp *interp,
    Tk_Window tkwin,
    Tk_PostscriptInfo psinfo,
    int x, int y, int width, int height,
    int prepass)
{
    BitmapMaster *masterPtr = (BitmapMaster *)clientData;
    BitmapModel *modelPtr = (BitmapModel *)clientData;
    Tcl_InterpState interpState;
    Tcl_Obj *psObj;

    if (prepass) {
	return TCL_OK;
    }

    /*
     * There is nothing to do for bitmaps with zero width or height.
     */

    if (width<=0 || height<=0 || masterPtr->width<=0 || masterPtr->height<=0){
    if (width<=0 || height<=0 || modelPtr->width<=0 || modelPtr->height<=0){
	return TCL_OK;
    }

    /*
     * Some postscript implementations cannot handle bitmap strings longer
     * than about 60k characters. If the bitmap data is that big or bigger,
     * we bail out.
     */

    if (masterPtr->width*masterPtr->height > 60000) {
    if (modelPtr->width*modelPtr->height > 60000) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"unable to generate postscript for bitmaps larger than 60000"
		" pixels", -1));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "MEMLIMIT", NULL);
	return TCL_ERROR;
    }

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







-
+


-
+







-
+




-
-
+
+







-
+


-
+







-
-
+
+







     * Color the background, if there is one. This step is skipped if the
     * background is transparent. If the background is not transparent and
     * there is no background mask, then color the complete rectangle that
     * encloses the bitmap. If there is a background mask, then only apply
     * color to the bits specified by the mask.
     */

    if ((masterPtr->bgUid != NULL) && (masterPtr->bgUid[0] != '\000')) {
    if ((modelPtr->bgUid != NULL) && (modelPtr->bgUid[0] != '\000')) {
	XColor color;

	TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), masterPtr->bgUid,
	TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), modelPtr->bgUid,
		&color);
	Tcl_ResetResult(interp);
	if (Tk_PostscriptColor(interp, psinfo, &color) != TCL_OK) {
	    goto error;
	}
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (masterPtr->maskData == NULL) {
	if (modelPtr->maskData == NULL) {
	    Tcl_AppendToObj(psObj,
		    "0 0 moveto 1 0 rlineto 0 1 rlineto -1 0 rlineto "
		    "closepath fill\n", -1);
	} else {
	    ImgBmapPsImagemask(psObj, masterPtr->width, masterPtr->height,
		    masterPtr->maskData);
	    ImgBmapPsImagemask(psObj, modelPtr->width, modelPtr->height,
		    modelPtr->maskData);
	}
    }

    /*
     * Draw the bitmap foreground, assuming there is one.
     */

    if ((masterPtr->fgUid != NULL) && (masterPtr->data != NULL)) {
    if ((modelPtr->fgUid != NULL) && (modelPtr->data != NULL)) {
	XColor color;

	TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), masterPtr->fgUid,
	TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), modelPtr->fgUid,
		&color);
	Tcl_ResetResult(interp);
	if (Tk_PostscriptColor(interp, psinfo, &color) != TCL_OK) {
	    goto error;
	}
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	ImgBmapPsImagemask(psObj, masterPtr->width, masterPtr->height,
		masterPtr->data);
	ImgBmapPsImagemask(psObj, modelPtr->width, modelPtr->height,
		modelPtr->data);
    }

    /*
     * Plug the accumulated postscript back into the result.
     */

    (void) Tcl_RestoreInterpState(interp, interpState);

Changes to generic/tkImgGIF.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14




15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10




11
12
13
14
15
16
17
18
19
20
21










-
-
-
-
+
+
+
+







/*
 * tkImgGIF.c --
 *
 *	A photo image file handler for GIF files. Reads 87a and 89a GIF files.
 *	At present, there only is a file write function. GIF images may be
 *	read using the -data option of the photo image. The data may be given
 *	as a binary string in a Tcl_Obj or by representing the data as BASE64
 *	encoded ascii. Derived from the giftoppm code found in the pbmplus
 *	package and tkImgFmtPPM.c in the tk4.0b2 distribution.
 *
 * Copyright (c) Reed Wade ([email protected]), University of Tennessee
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright (c) 1997 Australian National University
 * Copyright (c) 2005-2010 Donal K. Fellows
 * Copyright © Reed Wade ([email protected]), University of Tennessee
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 1997 Australian National University
 * Copyright © 2005-2010 Donal K. Fellows
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * This file also contains code from the giftoppm program, which is
 * copyrighted as follows:
 *
352
353
354
355
356
357
358
359

360
361
362

363
364
365
366
367
368
369
352
353
354
355
356
357
358

359
360
361

362
363
364
365
366
367
368
369







-
+


-
+







 *	The access position in f may change.
 *
 *----------------------------------------------------------------------
 */

static int
FileMatchGIF(
    TCL_UNUSED(Tcl_Interp *),		/* not used */
    TCL_UNUSED(Tcl_Interp *),	/* not used */
    Tcl_Channel chan,		/* The image file, open for reading. */
    TCL_UNUSED(const char *),	/* The name of the image file. */
    TCL_UNUSED(Tcl_Obj *),		/* User-specified format object, or NULL. */
    TCL_UNUSED(Tcl_Obj *),	/* User-specified format object, or NULL. */
    TCL_UNUSED(Tcl_Obj *),	/* metadata input, may be NULL */
    int *widthPtr, int *heightPtr,
				/* The dimensions of the image are returned
				 * here if the file is a valid raw GIF file. */
    TCL_UNUSED(Tcl_Obj *))	/* metadata return dict, may be NULL */
{
    GIFImageConfig gifConf;
850
851
852
853
854
855
856
857

858
859
860
861
862
863
864
850
851
852
853
854
855
856

857
858
859
860
861
862
863
864







-
+







    int *heightPtr,		/* where to put the string height */
    TCL_UNUSED(Tcl_Obj *))	/* metadata return dict, may be NULL */
{
    unsigned char *data, header[10];
    TkSizeT got, length;
    MFile handle;

    data = TkGetByteArrayFromObj(dataObj, &length);
    data = Tcl_GetByteArrayFromObj(dataObj, &length);

    /*
     * Header is a minimum of 10 bytes.
     */

    if (length < 10) {
	return 0;
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







-
+







    int width, int height,	/* image to copy */
    int srcX, int srcY,
    Tcl_Obj *metadataOutObj)	/* metadata return dict, may be NULL */
{
    MFile handle, *hdlPtr = &handle;
    TkSizeT 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
1177
1178
1179
1180
1181
1182
1183
1184
1185


1186
1187
1188
1189
1190
1191
1192
1177
1178
1179
1180
1181
1182
1183


1184
1185
1186
1187
1188
1189
1190
1191
1192







-
-
+
+







ReadImage(
    GIFImageConfig *gifConfPtr,
    Tcl_Interp *interp,
    unsigned char *imagePtr,
    Tcl_Channel chan,
    int len, int rows,
    unsigned char cmap[MAXCOLORMAPSIZE][4],
	TCL_UNUSED(int),
	TCL_UNUSED(int),
    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 };

Changes to generic/tkImgListFormat.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







-
-
-
-
+
+
+
+







 *      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.
 * Copyright © 1994 The Australian National University.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 2002-2003 Donal K. Fellows
 * Copyright © 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 ([email protected]),
 *              Department of Computer Science,
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







-
+







    const char *specString;
    TkSizeT charCount;

    /*
     * Find out which color format we have
     */

    specString = TkGetStringFromObj(specObj, &charCount);
    specString = Tcl_GetStringFromObj(specObj, &charCount);

    if (charCount == 0) {
        /* Empty string */
        *redPtr = *greenPtr = *bluePtr = *alphaPtr = 0;
        return TCL_OK;
    }
    if (charCount > TK_PHOTO_MAX_COLOR_CHARS) {

Changes to generic/tkImgPNG.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





-
-
+
+







/*
 * tkImgPNG.c --
 *
 *	A Tk photo image file handler for PNG files.
 *
 * Copyright (c) 2006-2008 Muonics, Inc.
 * Copyright (c) 2008 Donal K. Fellows
 * Copyright © 2006-2008 Muonics, Inc.
 * Copyright © 2008 Donal K. Fellows
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

332
333
334
335
336
337
338
339

340
341
342
343
344
345
346
332
333
334
335
336
337
338

339
340
341
342
343
344
345
346







-
+







     * 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));
643
644
645
646
647
648
649
650

651
652
653


654
655
656
657
658
659
660
643
644
645
646
647
648
649

650
651


652
653
654
655
656
657
658
659
660







-
+

-
-
+
+







    if (pngPtr->base64Data) {
	return ReadBase64(interp, pngPtr, destPtr, destSz, crcPtr);
    } else if (pngPtr->strDataBuf) {
	return ReadByteArray(interp, pngPtr, destPtr, destSz, crcPtr);
    }

    while (destSz) {
	size_t blockSz = PNG_MIN(destSz, PNG_BLOCK_SZ);
	TkSizeT blockSz = PNG_MIN(destSz, PNG_BLOCK_SZ);

	blockSz = (size_t)Tcl_Read(pngPtr->channel, (char *)destPtr, blockSz);
	if (blockSz == (size_t)-1) {
	blockSz = Tcl_Read(pngPtr->channel, (char *)destPtr, blockSz);
	if (blockSz == TCL_IO_FAILURE) {
	    /* TODO: failure info... */
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "channel read failed: %s", Tcl_PosixError(interp)));
	    return TCL_ERROR;
	}

	/*
1283
1284
1285
1286
1287
1288
1289
1290

1291
1292
1293
1294
1295
1296
1297
1283
1284
1285
1286
1287
1288
1289

1290
1291
1292
1293
1294
1295
1296
1297







-
+







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

1806
1807
1808
1809
1810
1811
1812
1813

1814
1815

1816
1817
1818
1819
1820
1821
1822
1806
1807
1808
1809
1810
1811
1812

1813
1814

1815
1816
1817
1818
1819
1820
1821
1822







-
+

-
+








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

1938
1939
1940
1941
1942
1943
1944
1945

1946
1947
1948
1949
1950
1951
1952
1938
1939
1940
1941
1942
1943
1944

1945
1946
1947
1948
1949
1950
1951
1952







-
+







    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(
2244
2245
2246
2247
2248
2249
2250
2251

2252
2253
2254
2255
2256

2257
2258
2259
2260
2261
2262
2263
2244
2245
2246
2247
2248
2249
2250

2251
2252
2253
2254
2255

2256
2257
2258
2259
2260
2261
2262
2263







-
+




-
+








	/*
	 * 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 (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",
2393
2394
2395
2396
2397
2398
2399
2400

2401
2402
2403
2404
2405
2406
2407
2393
2394
2395
2396
2397
2398
2399

2400
2401
2402
2403
2404
2405
2406
2407







-
+







    PNGImage *pngPtr)
{
    Tcl_Obj **objv = NULL;
    int objc = 0;
    static const char *const fmtOptions[] = {
	"-alpha", NULL
    };
    enum fmtOptions {
    enum fmtOptionsEnum {
	OPT_ALPHA
    };

    /*
     * Extract elements of format specification as a list.
     */

2430
2431
2432
2433
2434
2435
2436
2437

2438
2439
2440
2441
2442
2443
2444
2430
2431
2432
2433
2434
2435
2436

2437
2438
2439
2440
2441
2442
2443
2444







-
+







	    Tcl_WrongNumArgs(interp, 1, objv, "value");
	    return TCL_ERROR;
	}

	objc--;
	objv++;

	switch ((enum fmtOptions) optIndex) {
	switch ((enum fmtOptionsEnum) optIndex) {
	case OPT_ALPHA:
	    if (Tcl_GetDoubleFromObj(interp, objv[0],
		    &pngPtr->alpha) == TCL_ERROR) {
		return TCL_ERROR;
	    }

	    if ((pngPtr->alpha < 0.0) || (pngPtr->alpha > 1.0)) {
2814
2815
2816
2817
2818
2819
2820
2821

2822
2823
2824
2825
2826
2827
2828
2814
2815
2816
2817
2818
2819
2820

2821
2822
2823
2824
2825
2826
2827
2828







-
+







 */

static int
FileMatchPNG(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    Tcl_Channel chan,		/* The image file, open for reading. */
    TCL_UNUSED(const char *),	/* The name of the image file. */
    TCL_UNUSED(Tcl_Obj *),		/* User-specified format object, or NULL. */
    TCL_UNUSED(Tcl_Obj *),	/* User-specified format object, or NULL. */
    TCL_UNUSED(Tcl_Obj *),	/* metadata input, may be NULL */
    int *widthPtr, int *heightPtr,
				/* The dimensions of the image are returned
				 * here if the file is a valid raw GIF file. */
    TCL_UNUSED(Tcl_Obj *))	/* metadata return dict, may be NULL */
{
    PNGImage png;
2866
2867
2868
2869
2870
2871
2872
2873

2874
2875
2876
2877
2878
2879
2880
2866
2867
2868
2869
2870
2871
2872

2873
2874
2875
2876
2877
2878
2879
2880







-
+







    Tcl_Channel chan,		/* The image file, open for reading. */
    TCL_UNUSED(const char *),	/* The name of the image file. */
    Tcl_Obj *fmtObj,		/* User-specified format object, or NULL. */
    TCL_UNUSED(Tcl_Obj *),	/* metadata input, may be 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. */
    TCL_UNUSED(int),	/* Dimensions of block of photo image to be
    TCL_UNUSED(int),		/* Dimensions of block of photo image to be
				 * written to. */
    TCL_UNUSED(int),
    TCL_UNUSED(int),		/* Coordinates of top-left pixel to be used in
				 * image being read. */
    TCL_UNUSED(int),
    Tcl_Obj *metadataOutObj)	/* metadata return dict, may be NULL */
{
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
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







-
+










-
+







 *----------------------------------------------------------------------
 */

static int
StringMatchPNG(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    Tcl_Obj *pObjData,		/* the object containing the image data */
    TCL_UNUSED(Tcl_Obj *),		/* the image format object, or NULL */
    TCL_UNUSED(Tcl_Obj *),	/* the image format object, or NULL */
    TCL_UNUSED(Tcl_Obj *),	/* metadata input, may be NULL */
    int *widthPtr,		/* where to put the string width */
    int *heightPtr,		/* where to put the string height */
    TCL_UNUSED(Tcl_Obj *))	/* metadata return dict, may be NULL */
{
    PNGImage png;
    int match = 0;

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

2970
2971
2972
2973
2974
2975
2976
2977

2978
2979
2980
2981
2982
2983
2984
2970
2971
2972
2973
2974
2975
2976

2977
2978
2979
2980
2981
2982
2983
2984







-
+







StringReadPNG(
    Tcl_Interp *interp,		/* interpreter for reporting errors in */
    Tcl_Obj *pObjData,		/* object containing the image */
    Tcl_Obj *fmtObj,		/* format object, or NULL */
    TCL_UNUSED(Tcl_Obj *),	/* metadata input, may be NULL */
    Tk_PhotoHandle imageHandle,	/* the image to write this data into */
    int destX, int destY,	/* The rectangular region of the */
    TCL_UNUSED(int),	/* image to copy */
    TCL_UNUSED(int),		/* image to copy */
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    Tcl_Obj *metadataOutObj)	/* metadata return dict, may be NULL */
{
    PNGImage png;
    int result = TCL_ERROR;
3043
3044
3045
3046
3047
3048
3049
3050

3051
3052
3053
3054
3055
3056
3057
3043
3044
3045
3046
3047
3048
3049

3050
3051
3052
3053
3054
3055
3056
3057







-
+







     * objects immediately or store them in a multi-object rep?
     */

    if (pngPtr->objDataPtr) {
	TkSizeT objSz;
	unsigned char *destPtr;

	TkGetByteArrayFromObj(pngPtr->objDataPtr, &objSz);
	Tcl_GetByteArrayFromObj(pngPtr->objDataPtr, &objSz);

	if (objSz + srcSz > INT_MAX) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "image too large to store completely in byte array", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "TOO_LARGE", NULL);
	    return TCL_ERROR;
	}
3427
3428
3429
3430
3431
3432
3433
3434

3435
3436
3437
3438
3439
3440
3441
3427
3428
3429
3430
3431
3432
3433

3434
3435
3436
3437
3438
3439
3440
3441







-
+








    /*
     * 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;
}

/*
 *----------------------------------------------------------------------
3510
3511
3512
3513
3514
3515
3516
3517

3518
3519
3520
3521
3522
3523
3524
3510
3511
3512
3513
3514
3515
3516

3517
3518
3519
3520
3521
3522
3523
3524







-
+







    }
    Tcl_DStringFree(&buf);
    
    /*
     * Add a pHYs chunk if there is metadata for DPI and/or aspect
     * aspect = PPUy / PPUx
     * DPI = PPUx * 0.0254
     * The physical chunc consists of:
     * The physical chunk consists of:
     * - Points per meter in x direction (32 bit)
     * - Points per meter in x direction (32 bit)
     * - Unit specifier: 0: no unit (only aspect), 1: Points per meter
     */
    
    if (metadataInObj != NULL) {
	

Changes to generic/tkImgPPM.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





-
-
+
+







/*
 * tkImgPPM.c --
 *
 *	A photo image file handler for PPM (Portable PixMap) files.
 *
 * Copyright (c) 1994 The Australian National University.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1994 The Australian National University.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * Author: Paul Mackerras ([email protected]),
 *	Department of Computer Science,
 *	Australian National University.
90
91
92
93
94
95
96
97
98


99
100
101
102
103

104
105
106
107
108
109
110
111
112
113
114
115
90
91
92
93
94
95
96


97
98
99
100
101
102

103
104
105



106
107
108
109
110
111
112







-
-
+
+




-
+


-
-
-







 *
 *----------------------------------------------------------------------
 */

static int
FileMatchPPM(
    Tcl_Channel chan,		/* The image file, open for reading. */
    const char *fileName,	/* The name of the image file. */
    Tcl_Obj *format,		/* User-specified format string, or NULL. */
    TCL_UNUSED(const char *),	/* The name of the image file. */
    TCL_UNUSED(Tcl_Obj *),		/* User-specified format string, or NULL. */
    int *widthPtr, int *heightPtr,
				/* The dimensions of the image are returned
				 * here if the file is a valid raw PPM
				 * file. */
    Tcl_Interp *interp)		/* unused */
    TCL_UNUSED(Tcl_Interp *))		/* unused */
{
    int dummy;
    (void)fileName;
    (void)format;
    (void)interp;

    return ReadPPMFileHeader(chan, widthPtr, heightPtr, &dummy);
}

/*
 *----------------------------------------------------------------------
 *
130
131
132
133
134
135
136
137

138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
127
128
129
130
131
132
133

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

148
149
150
151
152
153
154







-
+













-







 */

static int
FileReadPPM(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    Tcl_Channel chan,		/* The image file, open for reading. */
    const char *fileName,	/* The name of the image file. */
    Tcl_Obj *format,		/* User-specified format string, or NULL. */
    TCL_UNUSED(Tcl_Obj *),		/* User-specified format string, or NULL. */
    Tk_PhotoHandle imageHandle,	/* The photo image to write into. */
    int destX, int destY,	/* Coordinates of top-left pixel in photo
				 * image to be written to. */
    int width, int height,	/* Dimensions of block of photo image to be
				 * written to. */
    int srcX, int srcY)		/* Coordinates of top-left pixel to be used in
				 * image being read. */
{
    int fileWidth, fileHeight, maxIntensity;
    int nLines, h, type, bytesPerChannel = 1;
    size_t nBytes, count;
    unsigned char *pixelPtr;
    Tk_PhotoImageBlock block;
    (void)format;

    type = ReadPPMFileHeader(chan, &fileWidth, &fileHeight, &maxIntensity);
    if (type == 0) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"couldn't read raw PPM header from file \"%s\"", fileName));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "NO_HEADER", NULL);
	return TCL_ERROR;
201
202
203
204
205
206
207
208

209
210
211
212
213
214
215
197
198
199
200
201
202
203

204
205
206
207
208
209
210
211







-
+








    if (Tk_PhotoExpand(interp, imageHandle,
	    destX + width, destY + height) != TCL_OK) {
	return TCL_ERROR;
    }

    if (srcY > 0) {
	Tcl_Seek(chan, (Tcl_WideInt)(srcY * block.pitch), SEEK_CUR);
	Tcl_Seek(chan, (long long)srcY * block.pitch, SEEK_CUR);
    }

    nLines = (MAX_MEMORY + block.pitch - 1) / block.pitch;
    if (nLines > height) {
	nLines = height;
    }
    if (nLines <= 0) {
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







-
+







-







 *----------------------------------------------------------------------
 */

static int
FileWritePPM(
    Tcl_Interp *interp,
    const char *fileName,
    Tcl_Obj *format,
    TCL_UNUSED(Tcl_Obj *),
    Tk_PhotoImageBlock *blockPtr)
{
    Tcl_Channel chan;
    int w, h, greenOffset, blueOffset;
    size_t nBytes;
    unsigned char *pixelPtr, *pixLinePtr;
    char header[16 + TCL_INTEGER_SPACE * 2];
    (void)format;

    chan = Tcl_OpenFileChannel(interp, fileName, "w", 0666);
    if (chan == NULL) {
	return TCL_ERROR;
    }

    if (Tcl_SetChannelOption(interp, chan, "-translation", "binary")
371
372
373
374
375
376
377
378

379
380
381
382
383
384
385
386
387
388
389
390
391
392
366
367
368
369
370
371
372

373
374
375
376
377
378
379

380
381
382
383
384
385
386







-
+






-







 *
 *----------------------------------------------------------------------
 */

static int
StringWritePPM(
    Tcl_Interp *interp,
    Tcl_Obj *format,
    TCL_UNUSED(Tcl_Obj *),
    Tk_PhotoImageBlock *blockPtr)
{
    int w, h, size, greenOffset, blueOffset;
    unsigned char *pixLinePtr, *byteArray;
    char header[16 + TCL_INTEGER_SPACE * 2];
    Tcl_Obj *byteArrayObj;
    (void)format;

    sprintf(header, "P6\n%d %d\n255\n", blockPtr->width, blockPtr->height);

    /*
     * Construct a byte array of the right size with the header and
     * get a pointer to the data part of it.
     */
448
449
450
451
452
453
454
455

456
457
458
459
460

461
462
463
464
465
466
467
468
469
470
471
442
443
444
445
446
447
448

449
450
451
452
453

454
455
456


457
458
459
460
461
462
463







-
+




-
+


-
-







 *
 *----------------------------------------------------------------------
 */

static int
StringMatchPPM(
    Tcl_Obj *dataObj,		/* The image data. */
    Tcl_Obj *format,		/* User-specified format string, or NULL. */
    TCL_UNUSED(Tcl_Obj *),		/* User-specified format string, or NULL. */
    int *widthPtr, int *heightPtr,
				/* The dimensions of the image are returned
				 * here if the file is a valid raw PPM
				 * file. */
    Tcl_Interp *interp)		/* unused */
    TCL_UNUSED(Tcl_Interp *))		/* unused */
{
    int dummy;
    (void)format;
    (void)interp;

    return ReadPPMStringHeader(dataObj, widthPtr, heightPtr,
	    &dummy, NULL, NULL);
}

/*
 *----------------------------------------------------------------------
485
486
487
488
489
490
491
492

493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
477
478
479
480
481
482
483

484
485
486
487
488
489
490
491
492
493
494
495
496

497
498
499
500
501
502
503







-
+












-







 *----------------------------------------------------------------------
 */

static int
StringReadPPM(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    Tcl_Obj *dataObj,		/* The image data. */
    Tcl_Obj *format,		/* User-specified format string, or NULL. */
    TCL_UNUSED(Tcl_Obj *),		/* User-specified format string, or NULL. */
    Tk_PhotoHandle imageHandle,	/* The photo image to write into. */
    int destX, int destY,	/* Coordinates of top-left pixel in photo
				 * image to be written to. */
    int width, int height,	/* Dimensions of block of photo image to be
				 * written to. */
    int srcX, int srcY)		/* Coordinates of top-left pixel to be used in
				 * image being read. */
{
    int fileWidth, fileHeight, maxIntensity;
    int nLines, nBytes, h, type, count, dataSize, bytesPerChannel = 1;
    unsigned char *pixelPtr, *dataBuffer;
    Tk_PhotoImageBlock block;
    (void)format;

    type = ReadPPMStringHeader(dataObj, &fileWidth, &fileHeight,
	    &maxIntensity, &dataBuffer, &dataSize);
    if (type == 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"couldn't read raw PPM header from string", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "NO_HEADER", NULL);
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
598
599
600
601
602
603
604

605
606
607
608
609
610
611







-







	    return TCL_ERROR;
	}
	if (maxIntensity < 0x00ff) {
	    for (p=pixelPtr,count=nBytes ; count>0 ; count--,p++,dataBuffer++) {
		*p = (((int) *dataBuffer) * 255)/maxIntensity;
	    }
	} else {
	    unsigned char *p;
	    unsigned int value;

	    for (p = pixelPtr,count=nBytes; count > 1; count-=2, p += 2) {
		value = ((unsigned int) p[0]) * 256 + ((unsigned int) p[1]);
		value = value * 255 / maxIntensity;
		p[0] = p[1] = (unsigned char) value;
	    }
773
774
775
776
777
778
779
780

781
782
783
784
785
786
787
763
764
765
766
767
768
769

770
771
772
773
774
775
776
777







-
+







{
#define BUFFER_SIZE 1000
    char buffer[BUFFER_SIZE], c;
    int i, numFields, type = 0;
    TkSizeT 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.

1
2
3
4
5
6
7
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
28
29







-
-
-
-
+
+
+
+










-
+
-
-







/*
 * tkImgPhInstance.c --
 *
 *	Implements the rendering of images of type "photo" for Tk. Photo
 *	images are stored in full color (32 bits per pixel including alpha
 *	channel) and displayed using dithering if necessary.
 *
 * Copyright (c) 1994 The Australian National University.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 2002-2008 Donal K. Fellows
 * Copyright (c) 2003 ActiveState Corporation.
 * Copyright © 1994 The Australian National University.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 2002-2008 Donal K. Fellows
 * Copyright © 2003 ActiveState Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * Author: Paul Mackerras ([email protected]),
 *	   Department of Computer Science,
 *	   Australian National University.
 */

#include "tkImgPhoto.h"
#ifdef MAC_OSX_TK
#include "tkPort.h"
#define TKPUTIMAGE_CAN_BLEND
#endif

/*
 * Declaration for internal Xlib function used here:
 */
#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TK)
#ifdef __cplusplus
extern "C" {
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54







-
+








#ifndef TKPUTIMAGE_CAN_BLEND
static void		BlendComplexAlpha(XImage *bgImg, PhotoInstance *iPtr,
			    int xOffset, int yOffset, int width, int height);
#endif
static int		IsValidPalette(PhotoInstance *instancePtr,
			    const char *palette);
static int		CountBits(pixel mask);
static int		CountBits(unsigned mask);
static void		GetColorTable(PhotoInstance *instancePtr);
static void		FreeColorTable(ColorTable *colorPtr, int force);
static void		AllocateColors(ColorTable *colorPtr);
static void		DisposeColorTable(ClientData clientData);
static int		ReclaimColors(ColorTableId *id, int numColors);

/*
64
65
66
67
68
69
70
71
72


73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

90
91
92
93
94
95
96

97
98

99
100
101
102
103



104
105
106
107

108
109
110
111
112
113
114
62
63
64
65
66
67
68


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

87
88
89
90
91
92
93

94
95

96
97
98



99
100
101
102
103
104

105
106
107
108
109
110
111
112







-
-
+
+
















-
+






-
+

-
+


-
-
-
+
+
+



-
+








/*
 *----------------------------------------------------------------------
 *
 * TkImgPhotoConfigureInstance --
 *
 *	This function is called to create displaying information for a photo
 *	image instance based on the configuration information in the master.
 *	It is invoked both when new instances are created and when the master
 *	image instance based on the configuration information in the model.
 *	It is invoked both when new instances are created and when the model
 *	is reconfigured.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Generates errors via Tcl_BackgroundException if there are problems in
 *	setting up the instance.
 *
 *----------------------------------------------------------------------
 */

void
TkImgPhotoConfigureInstance(
    PhotoInstance *instancePtr)	/* Instance to reconfigure. */
{
    PhotoMaster *masterPtr = instancePtr->masterPtr;
    PhotoModel *modelPtr = instancePtr->modelPtr;
    XImage *imagePtr;
    int bitsPerPixel;
    ColorTable *colorTablePtr;
    XRectangle validBox;

    /*
     * If the -palette configuration option has been set for the master, use
     * If the -palette configuration option has been set for the model, use
     * the value specified for our palette, but only if it is a valid palette
     * for our windows. Use the gamma value specified the master.
     * for our windows. Use the gamma value specified the model.
     */

    if ((masterPtr->palette && masterPtr->palette[0])
	    && IsValidPalette(instancePtr, masterPtr->palette)) {
	instancePtr->palette = masterPtr->palette;
    if ((modelPtr->palette && modelPtr->palette[0])
	    && IsValidPalette(instancePtr, modelPtr->palette)) {
	instancePtr->palette = modelPtr->palette;
    } else {
	instancePtr->palette = instancePtr->defaultPalette;
    }
    instancePtr->gamma = masterPtr->gamma;
    instancePtr->gamma = modelPtr->gamma;

    /*
     * If we don't currently have a color table, or if the one we have no
     * longer applies (e.g. because our palette or gamma has changed), get a
     * new one.
     */

164
165
166
167
168
169
170
171

172
173
174
175
176
177
178
179


180
181
182
183
184
185
186
187

188
189

190
191
192
193
194
195
196
162
163
164
165
166
167
168

169
170
171
172
173
174
175


176
177
178
179
180
181
182
183
184

185
186

187
188
189
190
191
192
193
194







-
+






-
-
+
+







-
+

-
+







#endif
		_XInitImageFuncPtrs(imagePtr);
	    }
	}
    }

    /*
     * If the user has specified a width and/or height for the master which is
     * If the user has specified a width and/or height for the model which is
     * different from our current width/height, set the size to the values
     * specified by the user. If we have no pixmap, we do this also, since it
     * has the side effect of allocating a pixmap for us.
     */

    if ((instancePtr->pixels == None) || (instancePtr->error == NULL)
	    || (instancePtr->width != masterPtr->width)
	    || (instancePtr->height != masterPtr->height)) {
	    || (instancePtr->width != modelPtr->width)
	    || (instancePtr->height != modelPtr->height)) {
	TkImgPhotoInstanceSetSize(instancePtr);
    }

    /*
     * Redither this instance if necessary.
     */

    if ((masterPtr->flags & IMAGE_CHANGED)
    if ((modelPtr->flags & IMAGE_CHANGED)
	    || (instancePtr->colorTablePtr != colorTablePtr)) {
	TkClipBox(masterPtr->validRegion, &validBox);
	TkClipBox(modelPtr->validRegion, &validBox);
	if ((validBox.width > 0) && (validBox.height > 0)) {
	    TkImgDitherInstance(instancePtr, validBox.x, validBox.y,
		    validBox.width, validBox.height);
	}
    }
}

212
213
214
215
216
217
218
219

220
221
222

223
224
225
226
227
228
229
210
211
212
213
214
215
216

217
218
219

220
221
222
223
224
225
226
227







-
+


-
+







 *----------------------------------------------------------------------
 */

ClientData
TkImgPhotoGet(
    Tk_Window tkwin,		/* Window in which the instance will be
				 * used. */
    ClientData masterData)	/* Pointer to our master structure for the
    ClientData modelData)	/* Pointer to our model structure for the
				 * image. */
{
    PhotoMaster *masterPtr = (PhotoMaster *)masterData;
    PhotoModel *modelPtr = (PhotoModel *)modelData;
    PhotoInstance *instancePtr;
    Colormap colormap;
    int mono, nRed, nGreen, nBlue, numVisuals;
    XVisualInfo visualInfo, *visInfoPtr;
    char buf[TCL_INTEGER_SPACE * 3];
    XColor *white, *black;
    XGCValues gcValues;
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







-
+








    /*
     * See if there is already an instance for windows using the same
     * colormap. If so then just re-use it.
     */

    colormap = Tk_Colormap(tkwin);
    for (instancePtr = masterPtr->instancePtr; instancePtr != NULL;
    for (instancePtr = modelPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	if ((colormap == instancePtr->colormap)
		&& (Tk_Display(tkwin) == instancePtr->display)) {
	    /*
	     * Re-use this instance.
	     */

282
283
284
285
286
287
288
289

290
291
292
293
294
295
296
297
298
299
300
301


302
303
304
305
306
307
308
280
281
282
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 image isn't already in use in a window with the same colormap. Make
     * a new instance of the image.
     */

    instancePtr = (PhotoInstance *)ckalloc(sizeof(PhotoInstance));
    instancePtr->masterPtr = masterPtr;
    instancePtr->modelPtr = modelPtr;
    instancePtr->display = Tk_Display(tkwin);
    instancePtr->colormap = Tk_Colormap(tkwin);
    Tk_PreserveColormap(instancePtr->display, instancePtr->colormap);
    instancePtr->refCount = 1;
    instancePtr->colorTablePtr = NULL;
    instancePtr->pixels = None;
    instancePtr->error = NULL;
    instancePtr->width = 0;
    instancePtr->height = 0;
    instancePtr->imagePtr = 0;
    instancePtr->nextPtr = masterPtr->instancePtr;
    masterPtr->instancePtr = instancePtr;
    instancePtr->nextPtr = modelPtr->instancePtr;
    modelPtr->instancePtr = instancePtr;

    /*
     * Obtain information about the visual and decide on the default palette.
     */

    visualInfo.screen = Tk_ScreenNumber(tkwin);
    visualInfo.visualid = XVisualIDFromVisual(Tk_Visual(tkwin));
354
355
356
357
358
359
360
361
362


363
364
365
366
367
368
369
352
353
354
355
356
357
358


359
360
361
362
363
364
365
366
367







-
-
+
+







    }
    instancePtr->defaultPalette = Tk_GetUid(buf);

    /*
     * Make a GC with background = black and foreground = white.
     */

    white = Tk_GetColor(masterPtr->interp, tkwin, "white");
    black = Tk_GetColor(masterPtr->interp, tkwin, "black");
    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;
378
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
391







-
-
+
+







    TkImgPhotoConfigureInstance(instancePtr);

    /*
     * If this is the first instance, must set the size of the image.
     */

    if (instancePtr->nextPtr == NULL) {
	Tk_ImageChanged(masterPtr->tkMaster, 0, 0, 0, 0,
		masterPtr->width, masterPtr->height);
	Tk_ImageChanged(modelPtr->tkModel, 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
427
428
410
411
412
413
414
415
416



417
418
419
420
421
422
423







-
-
-







 *	This should work on all platforms that set mask and shift data
 *	properly from the visualInfo. RGB is really only a 24+ bpp version
 *	whereas RGB15 is the correct version and works for 15bpp+, but it
 *	slower, so it's only used for 15bpp+.
 *
 *	Note that Win32 pre-defines those operations that we really need.
 *
 *	Note that on MacOS, if the background comes from a Retina display
 *	then it will be twice as wide and twice as high as the photoimage.
 *
 *----------------------------------------------------------------------
 */
#ifndef TKPUTIMAGE_CAN_BLEND
#ifndef _WIN32
#define GetRValue(rgb)	(UCHAR(((rgb) & red_mask) >> red_shift))
#define GetGValue(rgb)	(UCHAR(((rgb) & green_mask) >> green_shift))
#define GetBValue(rgb)	(UCHAR(((rgb) & blue_mask) >> blue_shift))
442
443
444
445
446
447
448
449
450


451
452
453
454
455
456
457
437
438
439
440
441
442
443


444
445
446
447
448
449
450
451
452







-
-
+
+







    PhotoInstance *iPtr,	/* Image instance to draw. */
    int xOffset, int yOffset,	/* X & Y offset into image instance to
				 * draw. */
    int width, int height)	/* Width & height of image to draw. */
{
    int x, y, line;
    unsigned long pixel;
    unsigned char r, g, b, alpha, unalpha, *masterPtr;
    unsigned char *alphaAr = iPtr->masterPtr->pix32;
    unsigned char r, g, b, alpha, unalpha, *modelPtr;
    unsigned char *alphaAr = iPtr->modelPtr->pix32;

    /*
     * This blending is an integer version of the Source-Over compositing rule
     * (see Porter&Duff, "Compositing Digital Images", proceedings of SIGGRAPH
     * 1984) that has been hard-coded (for speed) to work with targetting a
     * solid surface.
     *
500
501
502
503
504
505
506
507

508
509
510


511
512
513
514
515
516
517
518
519
520
521
522
523
524



525
526
527
528
529
530
531
495
496
497
498
499
500
501

502
503


504
505
506
507
508
509
510
511
512
513
514
515
516



517
518
519
520
521
522
523
524
525
526







-
+

-
-
+
+











-
-
-
+
+
+







    if (bgImg->depth < 24) {
	unsigned char red_mlen, green_mlen, blue_mlen;

	red_mlen = 8 - CountBits(red_mask >> red_shift);
	green_mlen = 8 - CountBits(green_mask >> green_shift);
	blue_mlen = 8 - CountBits(blue_mask >> blue_shift);
	for (y = 0; y < height; y++) {
	    line = (y + yOffset) * iPtr->masterPtr->width;
	    line = (y + yOffset) * iPtr->modelPtr->width;
	    for (x = 0; x < width; x++) {
		masterPtr = alphaAr + ((line + x + xOffset) * 4);
		alpha = masterPtr[3];
		modelPtr = alphaAr + ((line + x + xOffset) * 4);
		alpha = modelPtr[3];

		/*
		 * Ignore pixels that are fully transparent
		 */

		if (alpha) {
		    /*
		     * We could perhaps be more efficient than XGetPixel for
		     * 24 and 32 bit displays, but this seems "fast enough".
		     */

		    r = masterPtr[0];
		    g = masterPtr[1];
		    b = masterPtr[2];
		    r = modelPtr[0];
		    g = modelPtr[1];
		    b = modelPtr[2];
		    if (alpha != 255) {
			/*
			 * Only blend pixels that have some transparency
			 */

			unsigned char ra, ga, ba;

543
544
545
546
547
548
549
550

551
552
553


554
555
556
557
558
559
560
561
562
563
564
565
566
567



568
569
570
571
572
573
574
538
539
540
541
542
543
544

545
546


547
548
549
550
551
552
553
554
555
556
557
558
559



560
561
562
563
564
565
566
567
568
569







-
+

-
-
+
+











-
-
-
+
+
+







	    }
	}
	return;
    }
#endif /* !_WIN32 */

    for (y = 0; y < height; y++) {
	line = (y + yOffset) * iPtr->masterPtr->width;
	line = (y + yOffset) * iPtr->modelPtr->width;
	for (x = 0; x < width; x++) {
	    masterPtr = alphaAr + ((line + x + xOffset) * 4);
	    alpha = masterPtr[3];
	    modelPtr = alphaAr + ((line + x + xOffset) * 4);
	    alpha = modelPtr[3];

	    /*
	     * Ignore pixels that are fully transparent
	     */

	    if (alpha) {
		/*
		 * We could perhaps be more efficient than XGetPixel for 24
		 * and 32 bit displays, but this seems "fast enough".
		 */

		r = masterPtr[0];
		g = masterPtr[1];
		b = masterPtr[2];
		r = modelPtr[0];
		g = modelPtr[1];
		b = modelPtr[2];
		if (alpha != 255) {
		    /*
		     * Only blend pixels that have some transparency
		     */

		    unsigned char ra, ga, ba;

634
635
636
637
638
639
640
641

642
643
644
645
646
647
648
649
650
651
652
653

654
655
656
657
658
659
660
629
630
631
632
633
634
635

636
637
638
639
640
641
642
643
644
645
646
647

648
649
650
651
652
653
654
655







-
+











-
+








#ifdef TKPUTIMAGE_CAN_BLEND
    /*
     * If TkPutImage can handle RGBA Ximages directly there is
     * no need to call XGetImage or to do the Porter-Duff compositing by hand.
     */

    unsigned char *rgbaPixels = instancePtr->masterPtr->pix32;
    unsigned char *rgbaPixels = instancePtr->modelPtr->pix32;
    XImage *photo = XCreateImage(display, NULL, 32, ZPixmap, 0, (char*)rgbaPixels,
				 (unsigned int)instancePtr->width,
				 (unsigned int)instancePtr->height,
				 0, (unsigned int)(4 * instancePtr->width));
    TkPutImage(NULL, 0, display, drawable, instancePtr->gc,
	       photo, imageX, imageY, drawableX, drawableY,
	       (unsigned int) width, (unsigned int) height);
    photo->data = NULL;
    XDestroyImage(photo);
#else

    if ((instancePtr->masterPtr->flags & COMPLEX_ALPHA)
    if ((instancePtr->modelPtr->flags & COMPLEX_ALPHA)
	    && visInfo.depth >= 15
	    && (visInfo.c_class == DirectColor || visInfo.c_class == TrueColor)) {
	Tk_ErrorHandler handler;
	XImage *bgImg = NULL;

	/*
	 * Create an error handler to suppress the case where the input was
687
688
689
690
691
692
693
694

695
696
697
698
699
700
701

702
703
704
705
706
707
708
682
683
684
685
686
687
688

689
690
691
692
693
694
695

696
697
698
699
700
701
702
703







-
+






-
+







	TkPutImage(NULL, 0, display, drawable, instancePtr->gc,
		bgImg, 0, 0, drawableX, drawableY,
		(unsigned int) width, (unsigned int) height);
	XDestroyImage(bgImg);
	Tk_DeleteErrorHandler(handler);
    } else {
	/*
	 * masterPtr->region describes which parts of the image contain valid
	 * modelPtr->region describes which parts of the image contain valid
	 * data. We set this region as the clip mask for the gc, setting its
	 * origin appropriately, and use it when drawing the image.
	 */

    fallBack:
	TkSetRegion(display, instancePtr->gc,
		instancePtr->masterPtr->validRegion);
		instancePtr->modelPtr->validRegion);
	XSetClipOrigin(display, instancePtr->gc, drawableX - imageX,
		drawableY - imageY);
	XCopyArea(display, instancePtr->pixels, drawable, instancePtr->gc,
		imageX, imageY, (unsigned) width, (unsigned) height,
		drawableX, drawableY);
	XSetClipMask(display, instancePtr->gc, None);
	XSetClipOrigin(display, instancePtr->gc, 0, 0);
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
772
773
774
775
776
777
778

779
780
781
782
783
784


785
786
787


788
789
790
791
792
793


794
795
796
797
798
799
800
801
802







-
+





-
-
+
+

-
-
+
+




-
-
+
+







 *----------------------------------------------------------------------
 */

void
TkImgPhotoInstanceSetSize(
    PhotoInstance *instancePtr)	/* Instance whose size is to be changed. */
{
    PhotoMaster *masterPtr;
    PhotoModel *modelPtr;
    schar *newError, *errSrcPtr, *errDestPtr;
    int h, offset;
    XRectangle validBox;
    Pixmap newPixmap;

    masterPtr = instancePtr->masterPtr;
    TkClipBox(masterPtr->validRegion, &validBox);
    modelPtr = instancePtr->modelPtr;
    TkClipBox(modelPtr->validRegion, &validBox);

    if ((instancePtr->width != masterPtr->width)
	    || (instancePtr->height != masterPtr->height)
    if ((instancePtr->width != modelPtr->width)
	    || (instancePtr->height != modelPtr->height)
	    || (instancePtr->pixels == None)) {
	newPixmap = Tk_GetPixmap(instancePtr->display,
		RootWindow(instancePtr->display,
			instancePtr->visualInfo.screen),
		(masterPtr->width > 0) ? masterPtr->width: 1,
		(masterPtr->height > 0) ? masterPtr->height: 1,
		(modelPtr->width > 0) ? modelPtr->width: 1,
		(modelPtr->height > 0) ? modelPtr->height: 1,
		instancePtr->visualInfo.depth);
	if (!newPixmap) {
	    Tcl_Panic("Fail to create pixmap with Tk_GetPixmap in TkImgPhotoInstanceSetSize");
	}

	/*
	 * The following is a gross hack needed to properly support colormaps
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
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







-
-
+
+

-
+






-
+








-
-
+
+


-
+


-
-
-
-
+
+
+
+



-
+











-
-
+
+


-
+



-
+






-
+









-
-
+
+







		    instancePtr->gc, validBox.x, validBox.y,
		    validBox.width, validBox.height, validBox.x, validBox.y);
	    Tk_FreePixmap(instancePtr->display, instancePtr->pixels);
	}
	instancePtr->pixels = newPixmap;
    }

    if ((instancePtr->width != masterPtr->width)
	    || (instancePtr->height != masterPtr->height)
    if ((instancePtr->width != modelPtr->width)
	    || (instancePtr->height != modelPtr->height)
	    || (instancePtr->error == NULL)) {
	if (masterPtr->height > 0 && masterPtr->width > 0) {
	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(masterPtr->height * masterPtr->width
	    newError = (schar *)ckalloc(modelPtr->height * modelPtr->width
		    * 3 * sizeof(schar));

	    /*
	     * Zero the new array so that we don't get bogus error values
	     * propagating into areas we dither later.
	     */

	    if ((instancePtr->error != NULL)
		    && ((instancePtr->width == masterPtr->width)
		    || (validBox.width == masterPtr->width))) {
		    && ((instancePtr->width == modelPtr->width)
		    || (validBox.width == modelPtr->width))) {
		if (validBox.y > 0) {
		    memset(newError, 0, (size_t)
			    validBox.y * masterPtr->width * 3 * sizeof(schar));
			    validBox.y * modelPtr->width * 3 * sizeof(schar));
		}
		h = validBox.y + validBox.height;
		if (h < masterPtr->height) {
		    memset(newError + h*masterPtr->width*3, 0,
			    (size_t) (masterPtr->height - h)
			    * masterPtr->width * 3 * sizeof(schar));
		if (h < modelPtr->height) {
		    memset(newError + h*modelPtr->width*3, 0,
			    (size_t) (modelPtr->height - h)
			    * modelPtr->width * 3 * sizeof(schar));
		}
	    } else {
		memset(newError, 0, (size_t)
			masterPtr->height * masterPtr->width *3*sizeof(schar));
			modelPtr->height * modelPtr->width *3*sizeof(schar));
	    }
	} else {
	    newError = NULL;
	}

	if (instancePtr->error != NULL) {
	    /*
	     * Copy the common area over to the new array and free the old
	     * array.
	     */

	    if (masterPtr->width == instancePtr->width) {
		offset = validBox.y * masterPtr->width * 3;
	    if (modelPtr->width == instancePtr->width) {
		offset = validBox.y * modelPtr->width * 3;
		memcpy(newError + offset, instancePtr->error + offset,
			(size_t) validBox.height
			* masterPtr->width * 3 * sizeof(schar));
			* modelPtr->width * 3 * sizeof(schar));

	    } else if (validBox.width > 0 && validBox.height > 0) {
		errDestPtr = newError +
			(validBox.y * masterPtr->width + validBox.x) * 3;
			(validBox.y * modelPtr->width + validBox.x) * 3;
		errSrcPtr = instancePtr->error +
			(validBox.y * instancePtr->width + validBox.x) * 3;

		for (h = validBox.height; h > 0; --h) {
		    memcpy(errDestPtr, errSrcPtr,
			    validBox.width * 3 * sizeof(schar));
		    errDestPtr += masterPtr->width * 3;
		    errDestPtr += modelPtr->width * 3;
		    errSrcPtr += instancePtr->width * 3;
		}
	    }
	    ckfree(instancePtr->error);
	}

	instancePtr->error = newError;
    }

    instancePtr->width = masterPtr->width;
    instancePtr->height = masterPtr->height;
    instancePtr->width = modelPtr->width;
    instancePtr->height = modelPtr->height;
}

/*
 *----------------------------------------------------------------------
 *
 * IsValidPalette --
 *
1000
1001
1002
1003
1004
1005
1006
1007

1008
1009
1010
1011
1012
1013
1014
995
996
997
998
999
1000
1001

1002
1003
1004
1005
1006
1007
1008
1009







-
+







 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
CountBits(
    pixel mask)			/* Value to count the 1 bits in. */
    unsigned mask)			/* Value to count the 1 bits in. */
{
    int n;

    for (n=0 ; mask!=0 ; mask&=mask-1) {
	n++;
    }
    return n;
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
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







-
-
+
+

-
+















-
+

















-
+






-
+







    if (instancePtr->error != NULL) {
	ckfree(instancePtr->error);
    }
    if (instancePtr->colorTablePtr != NULL) {
	FreeColorTable(instancePtr->colorTablePtr, 1);
    }

    if (instancePtr->masterPtr->instancePtr == instancePtr) {
	instancePtr->masterPtr->instancePtr = instancePtr->nextPtr;
    if (instancePtr->modelPtr->instancePtr == instancePtr) {
	instancePtr->modelPtr->instancePtr = instancePtr->nextPtr;
    } else {
	for (prevPtr = instancePtr->masterPtr->instancePtr;
	for (prevPtr = instancePtr->modelPtr->instancePtr;
		prevPtr->nextPtr != instancePtr; prevPtr = prevPtr->nextPtr) {
	    /* Empty loop body. */
	}
	prevPtr->nextPtr = instancePtr->nextPtr;
    }
    Tk_FreeColormap(instancePtr->display, instancePtr->colormap);
    ckfree(instancePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkImgDitherInstance --
 *
 *	This function is called to update an area of an instance's pixmap by
 *	dithering the corresponding area of the master.
 *	dithering the corresponding area of the model.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The instance's pixmap gets updated.
 *
 *----------------------------------------------------------------------
 */

void
TkImgDitherInstance(
    PhotoInstance *instancePtr,	/* The instance to be updated. */
    int xStart, int yStart,	/* Coordinates of the top-left pixel in the
				 * block to be dithered. */
    int width, int height)	/* Dimensions of the block to be dithered. */
{
    PhotoMaster *masterPtr = instancePtr->masterPtr;
    PhotoModel *modelPtr = instancePtr->modelPtr;
    ColorTable *colorPtr = instancePtr->colorTablePtr;
    XImage *imagePtr;
    int nLines, bigEndian, i, c, x, y, xEnd, doDithering = 1;
    int bitsPerPixel, bytesPerLine, lineLength;
    unsigned char *srcLinePtr;
    schar *errLinePtr;
    pixel firstBit, word, mask;
    unsigned firstBit, word, mask;

    /*
     * Turn dithering off in certain cases where it is not needed (TrueColor,
     * DirectColor with many colors).
     */

    if ((colorPtr->visualInfo.c_class == DirectColor)
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
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







-
-
+
+




















-
+







     * recovering from the failure.
     */

    imagePtr->data = (char *)ckalloc(imagePtr->bytes_per_line * nLines);
    bigEndian = imagePtr->bitmap_bit_order == MSBFirst;
    firstBit = bigEndian? (1 << (imagePtr->bitmap_unit - 1)): 1;

    lineLength = masterPtr->width * 3;
    srcLinePtr = masterPtr->pix32 + (yStart * masterPtr->width + xStart) * 4;
    lineLength = modelPtr->width * 3;
    srcLinePtr = modelPtr->pix32 + (yStart * modelPtr->width + xStart) * 4;
    errLinePtr = instancePtr->error + yStart * lineLength + xStart * 3;
    xEnd = xStart + width;

    /*
     * Loop over the image, doing at most nLines lines before updating the
     * screen image.
     */

    for (; height > 0; height -= nLines) {
	unsigned char *dstLinePtr = (unsigned char *) imagePtr->data;
	int yEnd;

	if (nLines > height) {
	    nLines = height;
	}
	yEnd = yStart + nLines;
	for (y = yStart; y < yEnd; ++y) {
	    unsigned char *srcPtr = srcLinePtr;
	    schar *errPtr = errLinePtr;
	    unsigned char *destBytePtr = dstLinePtr;
	    pixel *destLongPtr = (pixel *) dstLinePtr;
	    unsigned *destLongPtr = (unsigned *) dstLinePtr;

	    if (colorPtr->flags & COLOR_WINDOW) {
		/*
		 * Color window. We dither the three components independently,
		 * using Floyd-Steinberg dithering, which propagates errors
		 * from the quantization of pixels to the pixels below and to
		 * the right.
1757
1758
1759
1760
1761
1762
1763
1764

1765
1766
1767
1768
1769
1770
1771
1752
1753
1754
1755
1756
1757
1758

1759
1760
1761
1762
1763
1764
1765
1766







-
+








			    c = (x > 0) ? errPtr[-3] * 7: 0;
			    if (y > 0) {
				if (x > 0) {
				    c += errPtr[-lineLength-3];
				}
				c += errPtr[-lineLength] * 5;
				if ((x + 1) < masterPtr->width) {
				if ((x + 1) < modelPtr->width) {
				    c += errPtr[-lineLength+3] * 3;
				}
			    }

			    /*
			     * Add the propagated error to the value of this
			     * component, quantize it, and store the
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
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







-
+













-
+











-
+





-
+







			 * image format is different from the pixel format in
			 * Win32. Eventually we need to fix the image code in
			 * Tk to use the Windows native image ordering. This
			 * would speed up the image code for all of the common
			 * sizes.
			 */

		    case NBBY * sizeof(pixel):
		    case NBBY * sizeof(unsigned):
			*destLongPtr++ = i;
			break;
#endif
		    default:
			XPutPixel(imagePtr, x - xStart, y - yStart,
				(unsigned) i);
		    }
		}

	    } else if (bitsPerPixel > 1) {
		/*
		 * Multibit monochrome window. The operation here is similar
		 * to the color window case above, except that there is only
		 * one component. If the master image is in color, use the
		 * one component. If the model image is in color, use the
		 * luminance computed as
		 *	0.344 * red + 0.5 * green + 0.156 * blue.
		 */

		for (x = xStart; x < xEnd; ++x) {
		    c = (x > 0) ? errPtr[-1] * 7: 0;
		    if (y > 0) {
			if (x > 0) {
			    c += errPtr[-lineLength-1];
			}
			c += errPtr[-lineLength] * 5;
			if (x + 1 < masterPtr->width) {
			if (x + 1 < modelPtr->width) {
			    c += errPtr[-lineLength+1] * 3;
			}
		    }
		    c = ((c + 2056) >> 4) - 128;

		    if (masterPtr->flags & COLOR_IMAGE) {
		    if (modelPtr->flags & COLOR_IMAGE) {
			c += (unsigned) (srcPtr[0] * 11 + srcPtr[1] * 16
				+ srcPtr[2] * 5 + 16) >> 5;
		    } else {
			c += srcPtr[0];
		    }
		    srcPtr += 4;

1876
1877
1878
1879
1880
1881
1882
1883

1884
1885
1886
1887
1888
1889
1890
1871
1872
1873
1874
1875
1876
1877

1878
1879
1880
1881
1882
1883
1884
1885







-
+







			 * image format is different from the pixel format in
			 * Win32. Eventually we need to fix the image code in
			 * Tk to use the Windows native image ordering. This
			 * would speed up the image code for all of the common
			 * sizes.
			 */

		    case NBBY * sizeof(pixel):
		    case NBBY * sizeof(unsigned):
			*destLongPtr++ = i;
			break;
#endif
		    default:
			XPutPixel(imagePtr, x - xStart, y - yStart,
				(unsigned) i);
		    }
1913
1914
1915
1916
1917
1918
1919
1920

1921
1922
1923
1924
1925
1926

1927
1928
1929
1930
1931
1932
1933
1908
1909
1910
1911
1912
1913
1914

1915
1916
1917
1918
1919
1920

1921
1922
1923
1924
1925
1926
1927
1928







-
+





-
+








		    c = (x > 0) ? errPtr[-1] * 7: 0;
		    if (y > 0) {
			if (x > 0) {
			    c += errPtr[-lineLength-1];
			}
			c += errPtr[-lineLength] * 5;
			if (x + 1 < masterPtr->width) {
			if (x + 1 < modelPtr->width) {
			    c += errPtr[-lineLength+1] * 3;
			}
		    }
		    c = ((c + 2056) >> 4) - 128;

		    if (masterPtr->flags & COLOR_IMAGE) {
		    if (modelPtr->flags & COLOR_IMAGE) {
			c += (unsigned)(srcPtr[0] * 11 + srcPtr[1] * 16
				+ srcPtr[2] * 5 + 16) >> 5;
		    } else {
			c += srcPtr[0];
		    }
		    srcPtr += 4;

1942
1943
1944
1945
1946
1947
1948
1949

1950
1951
1952
1953
1954
1955
1956
1937
1938
1939
1940
1941
1942
1943

1944
1945
1946
1947
1948
1949
1950
1951







-
+







		    } else {
			*errPtr++ = c;
		    }
		    mask = bigEndian? (mask >> 1): (mask << 1);
		}
		*destLongPtr = word;
	    }
	    srcLinePtr += masterPtr->width * 4;
	    srcLinePtr += modelPtr->width * 4;
	    errLinePtr += lineLength;
	    dstLinePtr += bytesPerLine;
	}

	/*
	 * Update the pixmap for this instance with the block of pixels that
	 * we have just computed.
1986
1987
1988
1989
1990
1991
1992
1993
1994


1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
1981
1982
1983
1984
1985
1986
1987


1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999







-
-
+
+











void
TkImgResetDither(
    PhotoInstance *instancePtr)
{
    if (instancePtr->error) {
	memset(instancePtr->error, 0,
		(size_t) instancePtr->masterPtr->width
		* instancePtr->masterPtr->height * 3 * sizeof(schar));
		(size_t) instancePtr->modelPtr->width
		* instancePtr->modelPtr->height * 3 * sizeof(schar));
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkImgPhoto.c.

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







-
-
-
-
+
+
+
+







/*
 * tkImgPhoto.c --
 *
 *	Implements images of type "photo" for Tk. Photo images are stored in
 *	full color (32 bits per pixel including alpha channel) and displayed
 *	using dithering if necessary.
 *
 * 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.
 * Copyright © 1994 The Australian National University.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 2002-2003 Donal K. Fellows
 * Copyright © 2003 ActiveState Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * Author: Paul Mackerras ([email protected]),
 *	   Department of Computer Science,
 *	   Australian National University.
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121







-
+








/*
 * 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_ImageMaster master,
			    const Tk_ImageType *typePtr, Tk_ImageModel model,
			    ClientData *clientDataPtr);
static void		ImgPhotoDelete(ClientData clientData);
static int		ImgPhotoPostscript(ClientData clientData,
			    Tcl_Interp *interp, Tk_Window tkwin,
			    Tk_PostscriptInfo psInfo, int x, int y, int width,
			    int height, int prepass);

163
164
165
166
167
168
169
170

171
172

173
174

175
176

177
178

179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195


196
197
198


199
200

201
202
203
204
205
206
207
163
164
165
166
167
168
169

170
171

172
173

174
175

176
177

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


194
195
196


197
198
199

200
201
202
203
204
205
206
207







-
+

-
+

-
+

-
+

-
+















-
-
+
+

-
-
+
+

-
+








/*
 * Information used for parsing configuration specifications:
 */

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_STRING, "-file", NULL, NULL,
	 NULL, offsetof(PhotoMaster, fileString), TK_CONFIG_NULL_OK, NULL},
	 NULL, offsetof(PhotoModel, fileString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_DOUBLE, "-gamma", NULL, NULL,
	 DEF_PHOTO_GAMMA, offsetof(PhotoMaster, gamma), 0, NULL},
	 DEF_PHOTO_GAMMA, offsetof(PhotoModel, gamma), 0, NULL},
    {TK_CONFIG_INT, "-height", NULL, NULL,
	 DEF_PHOTO_HEIGHT, offsetof(PhotoMaster, userHeight), 0, NULL},
	 DEF_PHOTO_HEIGHT, offsetof(PhotoModel, userHeight), 0, NULL},
    {TK_CONFIG_UID, "-palette", NULL, NULL,
	 DEF_PHOTO_PALETTE, offsetof(PhotoMaster, palette), 0, NULL},
	 DEF_PHOTO_PALETTE, offsetof(PhotoModel, palette), 0, NULL},
    {TK_CONFIG_INT, "-width", NULL, NULL,
	 DEF_PHOTO_WIDTH, offsetof(PhotoMaster, userWidth), 0, NULL},
	 DEF_PHOTO_WIDTH, offsetof(PhotoModel, userWidth), 0, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Forward declarations
 */

static void		PhotoFormatThreadExitProc(ClientData clientData);
static int		ImgPhotoCmd(ClientData clientData, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
static int		ParseSubcommandOptions(
			    struct SubcommandOptions *optPtr,
			    Tcl_Interp *interp, int allowedOptions,
			    int *indexPtr, int objc, Tcl_Obj *const objv[]);
static void		ImgPhotoCmdDeletedProc(ClientData clientData);
static int		ImgPhotoConfigureMaster(Tcl_Interp *interp,
			    PhotoMaster *masterPtr, int objc,
static int		ImgPhotoConfigureModel(Tcl_Interp *interp,
			    PhotoModel *modelPtr, int objc,
			    Tcl_Obj *const objv[], int flags);
static int		ToggleComplexAlphaIfNeeded(PhotoMaster *mPtr);
static int		ImgPhotoSetSize(PhotoMaster *masterPtr, int width,
static int		ToggleComplexAlphaIfNeeded(PhotoModel *mPtr);
static int		ImgPhotoSetSize(PhotoModel *modelPtr, int width,
			    int height);
static char *		ImgGetPhoto(PhotoMaster *masterPtr,
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,
			    Tcl_Obj *metadataInObj,
			    Tcl_Obj *metadataOutObj,
			    Tk_PhotoImageFormat **imageFormatPtr,
386
387
388
389
390
391
392
393

394
395
396
397
398

399
400
401

402
403
404
405
406
407
408
409
410
411
412
413










414
415
416
417
418
419
420


421
422
423
424

425
426
427
428
429
430
431
386
387
388
389
390
391
392

393
394
395
396
397

398
399
400

401
402
403










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


419
420
421
422
423

424
425
426
427
428
429
430
431







-
+




-
+


-
+


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





-
-
+
+



-
+







    Tcl_Interp *interp,		/* Interpreter for application containing
				 * image. */
    const char *name,		/* Name to use for image. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument objects for options (doesn't
				 * include image name or type). */
    TCL_UNUSED(const Tk_ImageType *),/* Pointer to our type record (not used). */
    Tk_ImageMaster master,	/* Token for image, to be used by us in later
    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. */
{
    PhotoMaster *masterPtr;
    PhotoModel *modelPtr;

    /*
     * Allocate and initialize the photo image master record.
     * Allocate and initialize the photo image model record.
     */

    masterPtr = (PhotoMaster *)ckalloc(sizeof(PhotoMaster));
    memset(masterPtr, 0, sizeof(PhotoMaster));
    masterPtr->tkMaster = master;
    masterPtr->interp = interp;
    masterPtr->imageCmd = Tcl_CreateObjCommand(interp, name, ImgPhotoCmd,
	    masterPtr, ImgPhotoCmdDeletedProc);
    masterPtr->palette = NULL;
    masterPtr->pix32 = NULL;
    masterPtr->instancePtr = NULL;
    masterPtr->validRegion = TkCreateRegion();
    modelPtr = (PhotoModel *)ckalloc(sizeof(PhotoModel));
    memset(modelPtr, 0, sizeof(PhotoModel));
    modelPtr->tkModel = model;
    modelPtr->interp = interp;
    modelPtr->imageCmd = Tcl_CreateObjCommand(interp, name, ImgPhotoCmd,
	    modelPtr, ImgPhotoCmdDeletedProc);
    modelPtr->palette = NULL;
    modelPtr->pix32 = NULL;
    modelPtr->instancePtr = NULL;
    modelPtr->validRegion = TkCreateRegion();

    /*
     * Process configuration options given in the image create command.
     */

    if (ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, 0) != TCL_OK) {
	ImgPhotoDelete(masterPtr);
    if (ImgPhotoConfigureModel(interp, modelPtr, objc, objv, 0) != TCL_OK) {
	ImgPhotoDelete(modelPtr);
	return TCL_ERROR;
    }

    *clientDataPtr = masterPtr;
    *clientDataPtr = modelPtr;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoCmd --
441
442
443
444
445
446
447
448

449
450
451
452
453
454
455
456
457
458
459
460
461
462
463

464
465
466
467
468
469
470
441
442
443
444
445
446
447

448
449
450
451
452
453
454
455
456
457
458
459
460
461
462

463
464
465
466
467
468
469
470







-
+














-
+







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
ImgPhotoCmd(
    ClientData clientData,	/* Information about photo master. */
    ClientData clientData,	/* Information about photo model. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const photoOptions[] = {
	"blank", "cget", "configure", "copy", "data", "get", "put",
	"read", "redither", "transparency", "write", NULL
    };
    enum PhotoOptions {
	PHOTO_BLANK, PHOTO_CGET, PHOTO_CONFIGURE, PHOTO_COPY, PHOTO_DATA,
	PHOTO_GET, PHOTO_PUT, PHOTO_READ, PHOTO_REDITHER, PHOTO_TRANS,
	PHOTO_WRITE
    };

    PhotoMaster *masterPtr = (PhotoMaster *)clientData;
    PhotoModel *modelPtr = (PhotoModel *)clientData;
    int result, index, x, y, width, height;
    struct SubcommandOptions options;
    unsigned char *pixelPtr;
    Tk_PhotoImageBlock block;
    Tk_PhotoImageFormat *imageFormat;
    Tk_PhotoImageFormatVersion3 *imageFormatVersion3;
    TkSizeT length;
487
488
489
490
491
492
493
494

495
496
497
498
499
500
501
502
503
504
505
506
507
508

509
510
511


512
513
514
515


516
517
518
519


520
521
522
523

524
525
526
527
528
529
530
531
532
533
534
535
536
537

538
539
540
541
542
543
544


545
546
547
548
549
550
551


552
553
554
555
556
557
558


559
560
561
562
563
564
565
566
567
568

569
570
571
572

573
574
575
576
577
578

579
580
581
582
583
584
585
586

587
588
589
590
591
592

593
594
595
596
597
598
599
600

601
602
603
604
605
606

607
608
609
610
611
612
613

614
615
616

617
618
619
620
621
622
623
487
488
489
490
491
492
493

494
495
496
497
498
499
500
501
502
503
504
505
506
507

508
509


510
511
512
513


514
515
516
517


518
519
520
521
522

523
524
525
526
527
528
529
530
531
532
533
534
535
536

537
538
539
540
541
542


543
544
545
546
547
548
549


550
551
552
553
554
555
556


557
558
559
560
561
562
563
564
565
566
567

568
569
570
571

572
573
574
575
576
577

578
579
580
581
582
583
584
585

586
587
588
589
590
591

592
593
594
595
596
597
598
599

600
601
602
603
604
605

606
607
608
609
610
611
612

613
614
615

616
617
618
619
620
621
622
623







-
+













-
+

-
-
+
+


-
-
+
+


-
-
+
+



-
+













-
+





-
-
+
+





-
-
+
+





-
-
+
+









-
+



-
+





-
+







-
+





-
+







-
+





-
+






-
+


-
+







    switch ((enum PhotoOptions) index) {
    case PHOTO_BLANK:
	/*
	 * photo blank command - just call Tk_PhotoBlank.
	 */

	if (objc == 2) {
	    Tk_PhotoBlank(masterPtr);
	    Tk_PhotoBlank(modelPtr);
	    return TCL_OK;
	} else {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    return TCL_ERROR;
	}

    case PHOTO_CGET: {
	const char *arg;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    return TCL_ERROR;
	}
	arg = TkGetStringFromObj(objv[2], &length);
	arg = Tcl_GetStringFromObj(objv[2], &length);
	if (strncmp(arg,"-data", length) == 0) {
	    if (masterPtr->dataString) {
		Tcl_SetObjResult(interp, masterPtr->dataString);
	    if (modelPtr->dataString) {
		Tcl_SetObjResult(interp, modelPtr->dataString);
	    }
	} else if (strncmp(arg,"-format", length) == 0) {
	    if (masterPtr->format) {
		Tcl_SetObjResult(interp, masterPtr->format);
	    if (modelPtr->format) {
		Tcl_SetObjResult(interp, modelPtr->format);
	    }
	} else if (strncmp(arg, "-metadata", length) == 0) {
	    if (masterPtr->metadata) {
		Tcl_SetObjResult(interp, masterPtr->metadata);
	    if (modelPtr->metadata) {
		Tcl_SetObjResult(interp, modelPtr->metadata);
	    }
	} else {
	    Tk_ConfigureValue(interp, Tk_MainWindow(interp), configSpecs,
		    (char *) masterPtr, 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 *) masterPtr, NULL, 0);
		    configSpecs, (char *) modelPtr, NULL, 0);
	    if (result != TCL_OK) {
		return result;
	    }
	    obj = Tcl_NewObj();
	    subobj = Tcl_NewStringObj("-data {} {} {}", 14);
	    if (masterPtr->dataString) {
		Tcl_ListObjAppendElement(NULL, subobj, masterPtr->dataString);
	    if (modelPtr->dataString) {
		Tcl_ListObjAppendElement(NULL, subobj, modelPtr->dataString);
	    } else {
		Tcl_AppendStringsToObj(subobj, " {}", NULL);
	    }
	    Tcl_ListObjAppendElement(interp, obj, subobj);
	    subobj = Tcl_NewStringObj("-format {} {} {}", 16);
	    if (masterPtr->format) {
		Tcl_ListObjAppendElement(NULL, subobj, masterPtr->format);
	    if (modelPtr->format) {
		Tcl_ListObjAppendElement(NULL, subobj, modelPtr->format);
	    } else {
		Tcl_AppendStringsToObj(subobj, " {}", NULL);
	    }
	    Tcl_ListObjAppendElement(interp, obj, subobj);
	    subobj = Tcl_NewStringObj("-metadata {} {} {}", 16);
	    if (masterPtr->metadata) {
		Tcl_ListObjAppendElement(NULL, subobj, masterPtr->metadata);
	    if (modelPtr->metadata) {
		Tcl_ListObjAppendElement(NULL, subobj, modelPtr->metadata);
	    } else {
		Tcl_AppendStringsToObj(subobj, " {}", NULL);
	    }
	    Tcl_ListObjAppendElement(interp, obj, subobj);
	    Tcl_ListObjAppendList(interp, obj, Tcl_GetObjResult(interp));
	    Tcl_SetObjResult(interp, obj);
	    return TCL_OK;

	} else if (objc == 3) {
	    const char *arg = TkGetStringFromObj(objv[2], &length);
	    const char *arg = Tcl_GetStringFromObj(objv[2], &length);

	    if (length > 1 && !strncmp(arg, "-data", length)) {
		Tcl_AppendResult(interp, "-data {} {} {}", NULL);
		if (masterPtr->dataString) {
		if (modelPtr->dataString) {
		    /*
		     * TODO: Modifying result is bad!
		     */

		    Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(interp),
			    masterPtr->dataString);
			    modelPtr->dataString);
		} else {
		    Tcl_AppendResult(interp, " {}", NULL);
		}
		return TCL_OK;
	    } else if (length > 1 &&
		    !strncmp(arg, "-format", length)) {
		Tcl_AppendResult(interp, "-format {} {} {}", NULL);
		if (masterPtr->format) {
		if (modelPtr->format) {
		    /*
		     * TODO: Modifying result is bad!
		     */

		    Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(interp),
			    masterPtr->format);
			    modelPtr->format);
		} else {
		    Tcl_AppendResult(interp, " {}", NULL);
		}
		return TCL_OK;
	    } else if (length > 1 &&
		!strncmp(arg, "-metadata", length)) {
		Tcl_AppendResult(interp, "-metadata {} {} {}", NULL);
		if (masterPtr->metadata) {
		if (modelPtr->metadata) {
		    /*
		     * TODO: Modifying result is bad!
		     */

		    Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(interp),
			masterPtr->metadata);
			modelPtr->metadata);
		} else {
		    Tcl_AppendResult(interp, " {}", NULL);
		}
		return TCL_OK;
	    } else {
		return Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
			configSpecs, (char *) masterPtr, arg, 0);
			configSpecs, (char *) modelPtr, arg, 0);
	    }
	} else {
	    return ImgPhotoConfigureMaster(interp, masterPtr, objc-2, objv+2,
	    return ImgPhotoConfigureModel(interp, modelPtr, objc-2, objv+2,
		    TK_CONFIG_ARGV_ONLY);
	}

    case PHOTO_COPY:
	/*
	 * photo copy command - first parse options.
	 */
668
669
670
671
672
673
674
675

676
677
678
679
680
681
682
668
669
670
671
672
673
674

675
676
677
678
679
680
681
682







-
+







	}

	/*
	 * Hack to pass through the message that the place we're coming from
	 * has a simple alpha channel.
	 */

	if (!(((PhotoMaster *) srcHandle)->flags & COMPLEX_ALPHA)) {
	if (!(((PhotoModel *) srcHandle)->flags & COMPLEX_ALPHA)) {
	    options.compositingRule |= SOURCE_IS_SIMPLE_ALPHA_PHOTO;
	}

	/*
	 * Fill in default values for unspecified parameters.
	 */

712
713
714
715
716
717
718
719

720
721
722
723
724
725
726
727
728
729
730
731
732
733

734
735
736
737
738
739
740
741
742
743
744
745


746
747
748
749
750
751
752
712
713
714
715
716
717
718

719
720
721
722
723
724
725
726
727
728
729
730
731
732

733
734
735
736
737
738
739
740
741
742
743


744
745
746
747
748
749
750
751
752







-
+













-
+










-
-
+
+







	 * Copy the image data over using Tk_PhotoPutZoomedBlock.
	 */

	block.pixelPtr += options.fromX * block.pixelSize
		+ options.fromY * block.pitch;
	block.width = options.fromX2 - options.fromX;
	block.height = options.fromY2 - options.fromY;
	result = Tk_PhotoPutZoomedBlock(interp, (Tk_PhotoHandle) masterPtr,
	result = Tk_PhotoPutZoomedBlock(interp, (Tk_PhotoHandle) modelPtr,
		&block, options.toX, options.toY, options.toX2 - options.toX,
		options.toY2 - options.toY, options.zoomX, options.zoomY,
		options.subsampleX, options.subsampleY,
		options.compositingRule);

	/*
	 * Set the destination image size if the -shrink option was specified.
	 * This has to be done _after_ copying the data. Otherwise, if source
	 * and destination are the same image, block.pixelPtr would point to
	 * an invalid memory block (bug [5239fd749b]).
	 */

	if (options.options & OPT_SHRINK) {
	    if (ImgPhotoSetSize(masterPtr, options.toX2,
	    if (ImgPhotoSetSize(modelPtr, options.toX2,
		    options.toY2) != TCL_OK) {
		if (options.background) {
		    Tk_FreeColor(options.background);
		}
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
		return TCL_ERROR;
	    }
	}
	Tk_ImageChanged(masterPtr->tkMaster, 0, 0, 0, 0,
		masterPtr->width, masterPtr->height);
	Tk_ImageChanged(modelPtr->tkModel, 0, 0, 0, 0,
		modelPtr->width, modelPtr->height);
	if (options.background) {
	    Tk_FreeColor(options.background);
	}
	return result;

    case PHOTO_DATA: {
        char *data = NULL;
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
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







-
-
-
-
+
+
+
+











-
-
+
+













-
+







		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((options.name == NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-option value ...?");
	    return TCL_ERROR;
	}
	if ((options.fromX > masterPtr->width)
		|| (options.fromY > masterPtr->height)
		|| (options.fromX2 > masterPtr->width)
		|| (options.fromY2 > masterPtr->height)) {
	if ((options.fromX > modelPtr->width)
		|| (options.fromY > modelPtr->height)
		|| (options.fromX2 > modelPtr->width)
		|| (options.fromY2 > modelPtr->height)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "coordinates for -from option extend outside image", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Fill in default values for unspecified parameters.
	 */

	if (!(options.options & OPT_FROM) || (options.fromX2 < 0)) {
	    options.fromX2 = masterPtr->width;
	    options.fromY2 = masterPtr->height;
	    options.fromX2 = modelPtr->width;
	    options.fromY2 = modelPtr->height;
	}
	if (!(options.options & OPT_FORMAT)) {
            options.format = Tcl_NewStringObj("default", -1);
            freeObj = options.format;
	}
	
	/*
	 * Use argument metadata if specified, otherwise the master metadata
	 */
	
	if (NULL != options.metadata) {
	    metadataIn = options.metadata;
	} else {
	    metadataIn = masterPtr->metadata;
	    metadataIn = modelPtr->metadata;
	}

	/*
	 * Search for an appropriate image string format handler.
	 */

	matched = 0;
870
871
872
873
874
875
876
877

878
879
880
881
882
883
884
870
871
872
873
874
875
876

877
878
879
880
881
882
883
884







-
+







	    goto dataErrorExit;
	}

	/*
	 * Call the handler's string write function to write out the image.
	 */

	data = ImgGetPhoto(masterPtr, &block, &options);
	data = ImgGetPhoto(modelPtr, &block, &options);

	if (stringWriteProc == NULL) {
	    result = (stringWriteProcVersion3)(interp,
		    options.format, metadataIn, &block);
	} else if (oldformat) {
	    Tcl_DString buffer;
	    typedef int (*OldStringWriteProc)(Tcl_Interp *interp,
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
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







-
-
+
+












-
+







            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 >= masterPtr->width)
		|| (y < 0) || (y >= masterPtr->height)) {
	if ((x < 0) || (x >= modelPtr->width)
		|| (y < 0) || (y >= modelPtr->height)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "%s get: coordinates out of range",
		    Tcl_GetString(objv[0])));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES",
		    NULL);
	    return TCL_ERROR;
	}

	/*
	 * Extract the value of the desired pixel and format it as a list.
	 */

	pixelPtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4;
	pixelPtr = modelPtr->pix32 + (y * modelPtr->width + x) * 4;
	channels[0] = Tcl_NewWideIntObj(pixelPtr[0]);
	channels[1] = Tcl_NewWideIntObj(pixelPtr[1]);
	channels[2] = Tcl_NewWideIntObj(pixelPtr[2]);
	channels[3] = Tcl_NewWideIntObj(pixelPtr[3]);
	Tcl_SetObjResult(interp, Tcl_NewListObj(channelCount, channels));
	return TCL_OK;
    }
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
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







-
+







-
+














-
+







		format = (Tcl_Obj *) Tcl_GetString(format);
	    }
	    data = (Tcl_Obj *) Tcl_GetString(data);
	}

	if (imageFormat != NULL) {
	    if (imageFormat->stringReadProc(interp, data, format,
		    (Tk_PhotoHandle) masterPtr, options.toX, options.toY,
		    (Tk_PhotoHandle) modelPtr, options.toX, options.toY,
		    options.toX2 - options.toX,
		    options.toY2 - options.toY, 0, 0) != TCL_OK) {
		return TCL_ERROR;
	    }
	} else {
	    if (imageFormatVersion3->stringReadProc(interp, data, format,
		    options.metadata,
		    (Tk_PhotoHandle) masterPtr, options.toX, options.toY,
		    (Tk_PhotoHandle) modelPtr, options.toX, options.toY,
		    options.toX2 - options.toX,
		    options.toY2 - options.toY, 0, 0,
		    NULL)
		    != TCL_OK) {
		return TCL_ERROR;
	    }
	}

	/*
	 * SB: is the next line really needed? The stringReadProc
	 * writes image data with Tk_PhotoPutBlock(), which in turn
	 * takes care to notify the changed image and to set/unset the
	 * IMAGE_CHANGED bit.
	 */
	masterPtr->flags |= IMAGE_CHANGED;
	modelPtr->flags |= IMAGE_CHANGED;

	return TCL_OK;
    }
    case PHOTO_READ: {
	Tcl_Obj *format;
	int result;

1142
1143
1144
1145
1146
1147
1148
1149

1150
1151
1152
1153
1154
1155
1156
1142
1143
1144
1145
1146
1147
1148

1149
1150
1151
1152
1153
1154
1155
1156







-
+







	}

	/*
	 * If the -shrink option was specified, set the size of the image.
	 */

	if (options.options & OPT_SHRINK) {
	    if (ImgPhotoSetSize(masterPtr, options.toX + width,
	    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);
		result = TCL_ERROR;
		goto readCleanup;
1165
1166
1167
1168
1169
1170
1171
1172

1173
1174
1175
1176
1177

1178
1179
1180
1181
1182
1183
1184
1165
1166
1167
1168
1169
1170
1171

1172
1173
1174
1175
1176

1177
1178
1179
1180
1181
1182
1183
1184







-
+




-
+







	format = options.format;
	if (oldformat && format) {
	    format = (Tcl_Obj *) Tcl_GetString(format);
	}
	if (imageFormat != NULL) {
	    result = imageFormat->fileReadProc(interp, chan,
		    Tcl_GetString(options.name),
		    format, (Tk_PhotoHandle) masterPtr, options.toX,
		    format, (Tk_PhotoHandle) modelPtr, options.toX,
		    options.toY, width, height, options.fromX, options.fromY);
	} else {
	    result = imageFormatVersion3->fileReadProc(interp, chan,
		    Tcl_GetString(options.name),
		    format, options.metadata, (Tk_PhotoHandle) masterPtr,
		    format, options.metadata, (Tk_PhotoHandle) modelPtr,
		    options.toX, options.toY, width, height, options.fromX,
		    options.fromY, NULL);
	}
readCleanup:
	if (chan != NULL) {
	    Tcl_Close(NULL, chan);
	}
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
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







-
-
-
-
-
+
+
+
+
+

-
+

-
-
-
+
+
+


-
+




-
-
-
+
+
+







	}

	/*
	 * Call Dither if any part of the image is not correctly dithered at
	 * present.
	 */

	x = masterPtr->ditherX;
	y = masterPtr->ditherY;
	if (masterPtr->ditherX != 0) {
	    Tk_DitherPhoto((Tk_PhotoHandle) masterPtr, x, y,
		    masterPtr->width - x, 1);
	x = modelPtr->ditherX;
	y = modelPtr->ditherY;
	if (modelPtr->ditherX != 0) {
	    Tk_DitherPhoto((Tk_PhotoHandle) modelPtr, x, y,
		    modelPtr->width - x, 1);
	}
	if (masterPtr->ditherY < masterPtr->height) {
	if (modelPtr->ditherY < modelPtr->height) {
	    x = 0;
	    Tk_DitherPhoto((Tk_PhotoHandle)masterPtr, 0,
		    masterPtr->ditherY, masterPtr->width,
		    masterPtr->height - masterPtr->ditherY);
	    Tk_DitherPhoto((Tk_PhotoHandle)modelPtr, 0,
		    modelPtr->ditherY, modelPtr->width,
		    modelPtr->height - modelPtr->ditherY);
	}

	if (y < masterPtr->height) {
	if (y < modelPtr->height) {
	    /*
	     * Tell the core image code that part of the image has changed.
	     */

	    Tk_ImageChanged(masterPtr->tkMaster, x, y,
		    (masterPtr->width - x), (masterPtr->height - y),
		    masterPtr->width, masterPtr->height);
	    Tk_ImageChanged(modelPtr->tkModel, x, y,
		    (modelPtr->width - x), (modelPtr->height - y),
		    modelPtr->width, modelPtr->height);
	}
	return TCL_OK;

    case PHOTO_TRANS: {
	static const char *const photoTransOptions[] = {
	    "get", "set", NULL
	};
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
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







-
-
+
+











-
+







		return TCL_ERROR;
	    }
	    boolMode = 1;
	    if (options.options & OPT_ALPHA) {
		boolMode = 0;
	    }

	    if ((x < 0) || (x >= masterPtr->width)
		    || (y < 0) || (y >= masterPtr->height)) {
	    if ((x < 0) || (x >= modelPtr->width)
		    || (y < 0) || (y >= modelPtr->height)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"%s transparency get: coordinates out of range",
			Tcl_GetString(objv[0])));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES",
			NULL);
		return TCL_ERROR;
	    }

	    /*
	     * Extract and return the desired value
	     */
	    pixelPtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4;
	    pixelPtr = modelPtr->pix32 + (y * modelPtr->width + x) * 4;
	    if (boolMode) {
		Tcl_SetObjResult(interp, Tcl_NewBooleanObj( ! pixelPtr[3]));
	    } else {
		Tcl_SetObjResult(interp, Tcl_NewWideIntObj(pixelPtr[3]));
	    }
	    return TCL_OK;
	}
1328
1329
1330
1331
1332
1333
1334
1335
1336


1337
1338
1339
1340
1341
1342
1343
1328
1329
1330
1331
1332
1333
1334


1335
1336
1337
1338
1339
1340
1341
1342
1343







-
-
+
+







		return TCL_ERROR;
	    }
	    boolMode = 1;
	    if (options.options & OPT_ALPHA) {
		boolMode = 0;
	    }

	    if ((x < 0) || (x >= masterPtr->width)
		|| (y < 0) || (y >= masterPtr->height)) {
	    if ((x < 0) || (x >= modelPtr->width)
		|| (y < 0) || (y >= modelPtr->height)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"%s transparency set: coordinates out of range",
			Tcl_GetString(objv[0])));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES",
			NULL);
		return TCL_ERROR;
	    }
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
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







-
+

















-
-
+
+

-
-
+
+








-
-
-
+
+
+







		}
	    }

	    /*
	     * Set new alpha value for the pixel
	     */

	    pixelPtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4;
	    pixelPtr = modelPtr->pix32 + (y * modelPtr->width + x) * 4;
	    if (boolMode) {
		pixelPtr[3] = newVal ? 0 : 255;
	    } else {
		pixelPtr[3] = newVal;
	    }

	    /*
	     * Update the validRegion of the image
	     */

	    setBox.x = x;
	    setBox.y = y;
	    setBox.width = 1;
	    setBox.height = 1;
	    modRegion = TkCreateRegion();
	    TkUnionRectWithRegion(&setBox, modRegion, modRegion);
	    if (pixelPtr[3]) {
		TkUnionRectWithRegion(&setBox, masterPtr->validRegion,
			masterPtr->validRegion);
		TkUnionRectWithRegion(&setBox, modelPtr->validRegion,
			modelPtr->validRegion);
	    } else {
		TkSubtractRegion(masterPtr->validRegion, modRegion,
			masterPtr->validRegion);
		TkSubtractRegion(modelPtr->validRegion, modRegion,
			modelPtr->validRegion);
	    }
	    TkDestroyRegion(modRegion);

	    /*
	     * Inform the generic image code that the image
	     * has (potentially) changed.
	     */

	    Tk_ImageChanged(masterPtr->tkMaster, x, y, 1, 1,
		    masterPtr->width, masterPtr->height);
	    masterPtr->flags &= ~IMAGE_CHANGED;
	    Tk_ImageChanged(modelPtr->tkModel, x, y, 1, 1,
		    modelPtr->width, modelPtr->height);
	    modelPtr->flags &= ~IMAGE_CHANGED;
	    return TCL_OK;
	}

	}
	Tcl_Panic("unexpected fallthrough");
    }

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







-
-
-
-
+
+
+
+













-
-
+
+

















-
+







		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((options.name == NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "fileName ?-option value ...?");
	    return TCL_ERROR;
	}
	if ((options.fromX > masterPtr->width)
		|| (options.fromY > masterPtr->height)
		|| (options.fromX2 > masterPtr->width)
		|| (options.fromY2 > masterPtr->height)) {
	if ((options.fromX > modelPtr->width)
		|| (options.fromY > modelPtr->height)
		|| (options.fromX2 > modelPtr->width)
		|| (options.fromY2 > modelPtr->height)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "coordinates for -from option extend outside image", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Fill in default values for unspecified parameters. Note that a
	 * missing -format flag results in us having a guess from the file
	 * extension. [Bug 2983824]
	 */

	if (!(options.options & OPT_FROM) || (options.fromX2 < 0)) {
	    options.fromX2 = masterPtr->width;
	    options.fromY2 = masterPtr->height;
	    options.fromX2 = modelPtr->width;
	    options.fromY2 = modelPtr->height;
	}
	if (options.format == NULL) {
	    fmtString = GetExtension(Tcl_GetString(options.name));
	    usedExt = (fmtString != NULL);
	} else {
	    fmtString = Tcl_GetString(options.format);
	    usedExt = 0;
	}

	
	/*
	 * Use argument metadata if specified, otherwise the master metadata
	 */
	
	if (NULL != options.metadata) {
	    metadataIn = options.metadata;
	} else {
	    metadataIn = masterPtr->metadata;
	    metadataIn = modelPtr->metadata;
	}

	/*
	 * Search for an appropriate image file format handler, and give an
	 * error if none is found.
	 */

1559
1560
1561
1562
1563
1564
1565
1566

1567
1568
1569
1570
1571
1572
1573
1559
1560
1561
1562
1563
1564
1565

1566
1567
1568
1569
1570
1571
1572
1573







-
+







	    return TCL_ERROR;
	}

	/*
	 * Call the handler's file write function to write out the image.
	 */

	data = ImgGetPhoto(masterPtr, &block, &options);
	data = ImgGetPhoto(modelPtr, &block, &options);
	format = options.format;
	if (oldformat && format) {
	    format = (Tcl_Obj *) Tcl_GetString(options.format);
	}
	if (imageFormat != NULL) {
	    result = imageFormat->fileWriteProc(interp,
		    Tcl_GetString(options.name), format, &block);
1671
1672
1673
1674
1675
1676
1677
1678

1679
1680
1681
1682
1683
1684
1685
1671
1672
1673
1674
1675
1676
1677

1678
1679
1680
1681
1682
1683
1684
1685







-
+








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







-
+







-
+









-
+

-
+







    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION", NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoConfigureMaster --
 * ImgPhotoConfigureModel --
 *
 *	This function is called when a photo image is created or reconfigured.
 *	It processes configuration options and resets any instances of the
 *	image.
 *
 * Results:
 *	A standard Tcl return value. If TCL_ERROR is returned then an error
 *	message is left in the masterPtr->interp's result.
 *	message is left in the modelPtr->interp's result.
 *
 * Side effects:
 *	Existing instances of the image will be redisplayed to match the new
 *	configuration options.
 *
 *----------------------------------------------------------------------
 */

static int
ImgPhotoConfigureMaster(
ImgPhotoConfigureModel(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    PhotoMaster *masterPtr,	/* Pointer to data structure describing
    PhotoModel *modelPtr,	/* Pointer to data structure describing
				 * overall photo image to (re)configure. */
    int objc,			/* Number of entries in objv. */
    Tcl_Obj *const objv[],	/* Pairs of configuration options for image. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget, such
				 * as TK_CONFIG_ARGV_ONLY. */
{
    PhotoInstance *instancePtr;
1962
1963
1964
1965
1966
1967
1968
1969

1970
1971
1972
1973
1974
1975
1976
1962
1963
1964
1965
1966
1967
1968

1969
1970
1971
1972
1973
1974
1975
1976







-
+







    Tcl_Channel chan;
    Tk_PhotoImageFormat *imageFormat;
    Tk_PhotoImageFormatVersion3 *imageFormatVersion3;
    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);
	args[j] = Tcl_GetStringFromObj(objv[i], &length);
	if ((length > 1) && (args[j][0] == '-')) {
	    if ((args[j][1] == 'd') &&
		    !strncmp(args[j], "-data", length)) {
		if (++i < objc) {
		    data = objv[i];
		    j--;
		} else {
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
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







-
+

-
+






-
+



-
-
+
+






-
+









-
-
-
+
+
+








-
+





-
-
+
+

-
+













-
-
+
+

-
+



-
+


















-
-
+
+

-
+






-
-
+
+











-
-
-
+
+
+














-
+

















-
-
+
+





-
+







-
+





-
-
+
+



-
-
+
+










-
+


-
-
-
+
+
+








-
-
+
+




-
+





-
-
+
+








-
+




-

-
+






-
+




















-
-
+
+






-
-
-
-
+
+
+
+







-
+









-
-
+
+


-
-
-
+
+
+








-
+








-
-
-
+
+
+











-
+







    /*
     * Save the current values for fileString and dataString, so we can tell
     * if the user specifies them anew. IMPORTANT: if the format changes we
     * have to interpret "-file" and "-data" again as well! It might be that
     * the format string influences how "-data" or "-file" is interpreted.
     */

    oldFileString = masterPtr->fileString;
    oldFileString = modelPtr->fileString;
    if (oldFileString == NULL) {
	oldData = masterPtr->dataString;
	oldData = modelPtr->dataString;
	if (oldData != NULL) {
	    Tcl_IncrRefCount(oldData);
	}
    } else {
	oldData = NULL;
    }
    oldFormat = masterPtr->format;
    oldFormat = modelPtr->format;
    if (oldFormat != NULL) {
	Tcl_IncrRefCount(oldFormat);
    }
    oldPaletteString = masterPtr->palette;
    oldGamma = masterPtr->gamma;
    oldPaletteString = modelPtr->palette;
    oldGamma = modelPtr->gamma;

    /*
     * Process the configuration options specified.
     */

    if (Tk_ConfigureWidget(interp, Tk_MainWindow(interp), configSpecs,
	    j, args, (char *) masterPtr, flags) != TCL_OK) {
	    j, args, (char *) modelPtr, flags) != TCL_OK) {
	ckfree(args);
	goto errorExit;
    }
    ckfree(args);

    /*
     * Regard the empty string for -file, -data, -format or -metadata as the null value.
     */

    if ((masterPtr->fileString != NULL) && (masterPtr->fileString[0] == 0)) {
	ckfree(masterPtr->fileString);
	masterPtr->fileString = NULL;
    if ((modelPtr->fileString != NULL) && (modelPtr->fileString[0] == 0)) {
	ckfree(modelPtr->fileString);
	modelPtr->fileString = NULL;
    }
    if (data) {
	/*
	 * Force into ByteArray format, which most (all) image handlers will
	 * use anyway. Empty length means ignore the -data option.
	 */
	TkSizeT bytesize;

	(void) TkGetByteArrayFromObj(data, &bytesize);
	(void) Tcl_GetByteArrayFromObj(data, &bytesize);
	if (bytesize) {
	    Tcl_IncrRefCount(data);
	} else {
	    data = NULL;
	}
	if (masterPtr->dataString) {
	    Tcl_DecrRefCount(masterPtr->dataString);
	if (modelPtr->dataString) {
	    Tcl_DecrRefCount(modelPtr->dataString);
	}
	masterPtr->dataString = data;
	modelPtr->dataString = data;
    }
    if (format) {
	/*
	 * Stringify to ignore -format "". It may come in as a list or other
	 * object.
	 */

	(void) Tcl_GetString(format);
	if (format->length) {
	    Tcl_IncrRefCount(format);
	} else {
	    format = NULL;
	}
	if (masterPtr->format) {
	    Tcl_DecrRefCount(masterPtr->format);
	if (modelPtr->format) {
	    Tcl_DecrRefCount(modelPtr->format);
	}
	masterPtr->format = format;
	modelPtr->format = format;
    }
    if (metadataInObj) {
	/*
	 * make -metadata a dict.
	 * Make -metadata a dict.
	 * Take also empty metadatas as this may be a sign to replace
	 * existing metadata.
	 */
	int dictSize;

	if (TCL_OK != Tcl_DictObjSize(interp,metadataInObj, &dictSize)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "value for \"-metadata\" not a dict", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
		    "UNRECOGNIZED_DATA", NULL);
	    return TCL_ERROR;
	}

	if (dictSize > 0) {
	    Tcl_IncrRefCount(metadataInObj);
	} else {
	    metadataInObj = NULL;
	}
	if (masterPtr->metadata) {
	    Tcl_DecrRefCount(masterPtr->metadata);
	if (modelPtr->metadata) {
	    Tcl_DecrRefCount(modelPtr->metadata);
	}
	masterPtr->metadata = metadataInObj;
	modelPtr->metadata = metadataInObj;
    }
    /*
     * Set the image to the user-requested size, if any, and make sure storage
     * is correctly allocated for this image.
     */

    if (ImgPhotoSetSize(masterPtr, masterPtr->width,
	    masterPtr->height) != TCL_OK) {
    if (ImgPhotoSetSize(modelPtr, modelPtr->width,
	    modelPtr->height) != TCL_OK) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
	Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	goto errorExit;
    }

    /*
     * Read in the image from the file or string if the user has specified the
     * -file or -data option.
     */

    if ((masterPtr->fileString != NULL)
	    && ((masterPtr->fileString != oldFileString)
	    || (masterPtr->format != oldFormat))) {
    if ((modelPtr->fileString != NULL)
	    && ((modelPtr->fileString != oldFileString)
	    || (modelPtr->format != oldFormat))) {

	/*
	 * Prevent file system access in a safe interpreter.
	 */

	if (Tcl_IsSafe(interp)) {
	    Tcl_ResetResult(interp);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't get image from a file in a safe interpreter",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "PHOTO_FILE", NULL);
	    goto errorExit;
	}

	chan = Tcl_OpenFileChannel(interp, masterPtr->fileString, "r", 0);
	chan = Tcl_OpenFileChannel(interp, modelPtr->fileString, "r", 0);
	if (chan == NULL) {
	    goto errorExit;
	}

	/*
	 * Flag that we want the metadata result dict
	 */

	metadataOutObj = Tcl_NewDictObj();
	Tcl_IncrRefCount(metadataOutObj);

	/*
	 * -translation binary also sets -encoding binary
	 */

	if ((Tcl_SetChannelOption(interp, chan,
		"-translation", "binary") != TCL_OK) ||
		(MatchFileFormat(interp, chan, masterPtr->fileString,
			masterPtr->format, masterPtr->metadata, metadataOutObj,
		(MatchFileFormat(interp, chan, modelPtr->fileString,
			modelPtr->format, modelPtr->metadata, metadataOutObj,
			&imageFormat, &imageFormatVersion3,
			&imageWidth, &imageHeight, &oldformat) != TCL_OK)) {
	    Tcl_Close(NULL, chan);
	    goto errorExit;
	}
	result = ImgPhotoSetSize(masterPtr, imageWidth, imageHeight);
	result = ImgPhotoSetSize(modelPtr, imageWidth, imageHeight);
	if (result != TCL_OK) {
	    Tcl_Close(NULL, chan);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
	    Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    goto errorExit;
	}
	tempformat = masterPtr->format;
	tempformat = modelPtr->format;
	if (oldformat && tempformat) {
	    tempformat = (Tcl_Obj *) Tcl_GetString(tempformat);
	}
	if (imageFormat != NULL) {
	    result = imageFormat->fileReadProc(interp, chan,
		    masterPtr->fileString, tempformat,
		    (Tk_PhotoHandle) masterPtr,
		    modelPtr->fileString, tempformat,
		    (Tk_PhotoHandle) modelPtr,
		    0, 0, imageWidth, imageHeight, 0, 0);
	} else {
	    result = imageFormatVersion3->fileReadProc(interp, chan,
		    masterPtr->fileString, tempformat, masterPtr->metadata,
		    (Tk_PhotoHandle) masterPtr,
		    modelPtr->fileString, tempformat, modelPtr->metadata,
		    (Tk_PhotoHandle) modelPtr,
		    0, 0, imageWidth, imageHeight, 0, 0,
		    metadataOutObj);
	}

	Tcl_Close(NULL, chan);
	if (result != TCL_OK) {
	    goto errorExit;
	}

	Tcl_ResetResult(interp);
	masterPtr->flags |= IMAGE_CHANGED;
	modelPtr->flags |= IMAGE_CHANGED;
    }

    if ((masterPtr->fileString == NULL) && (masterPtr->dataString != NULL)
	    && ((masterPtr->dataString != oldData)
		    || (masterPtr->format != oldFormat))) {
    if ((modelPtr->fileString == NULL) && (modelPtr->dataString != NULL)
	    && ((modelPtr->dataString != oldData)
		    || (modelPtr->format != oldFormat))) {

	/*
	 * Flag that we want the metadata result dict
	 */

	metadataOutObj = Tcl_NewDictObj();
	Tcl_IncrRefCount(metadataOutObj);

	if (MatchStringFormat(interp, masterPtr->dataString,
		masterPtr->format, masterPtr->metadata, metadataOutObj,
	if (MatchStringFormat(interp, modelPtr->dataString,
		modelPtr->format, modelPtr->metadata, metadataOutObj,
		&imageFormat, &imageFormatVersion3, &imageWidth,
		&imageHeight, &oldformat) != TCL_OK) {
	    goto errorExit;
	}
	if (ImgPhotoSetSize(masterPtr, imageWidth, imageHeight) != TCL_OK) {
	if (ImgPhotoSetSize(modelPtr, imageWidth, imageHeight) != TCL_OK) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
	    Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    goto errorExit;
	}
	tempformat = masterPtr->format;
	tempdata = masterPtr->dataString;
	tempformat = modelPtr->format;
	tempdata = modelPtr->dataString;
	if (oldformat) {
	    if (tempformat) {
		tempformat = (Tcl_Obj *) Tcl_GetString(tempformat);
	    }
	    tempdata = (Tcl_Obj *) Tcl_GetString(tempdata);
	}
	if (imageFormat != NULL) {
	    if (imageFormat->stringReadProc(interp, tempdata, tempformat,
		    (Tk_PhotoHandle) masterPtr, 0, 0, imageWidth, imageHeight,
		    (Tk_PhotoHandle) modelPtr, 0, 0, imageWidth, imageHeight,
		    0, 0) != TCL_OK) {
		goto errorExit;
	    }
	} else {
	    
	    if (imageFormatVersion3->stringReadProc(interp, tempdata, tempformat,
		    masterPtr->metadata, (Tk_PhotoHandle) masterPtr, 0, 0,
		    modelPtr->metadata, (Tk_PhotoHandle) modelPtr, 0, 0,
		    imageWidth, imageHeight, 0, 0, metadataOutObj) != TCL_OK) {
		goto errorExit;
	    }
	}

	Tcl_ResetResult(interp);
	masterPtr->flags |= IMAGE_CHANGED;
	modelPtr->flags |= IMAGE_CHANGED;
    }

    /*
     * Merge driver returned metadata and master metadata
     */
    if (metadataOutObj != NULL) {
	int dictSize;
	if (TCL_OK != Tcl_DictObjSize(interp,metadataOutObj, &dictSize)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "driver metadata not a dict", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
		    "UNRECOGNIZED_DATA", NULL);
	    goto errorExit;
	}
	if (dictSize > 0) {

	    /*
	     * We have driver return metadata
	     */
	    
	    if (masterPtr->metadata == NULL) {
		masterPtr->metadata = metadataOutObj;
	    if (modelPtr->metadata == NULL) {
		modelPtr->metadata = metadataOutObj;
		metadataOutObj = NULL;
	    } else {
		Tcl_DictSearch search;
		Tcl_Obj *key, *value;
		int done;

		if (Tcl_IsShared(masterPtr->metadata)) {
		    Tcl_DecrRefCount(masterPtr->metadata);
		    masterPtr->metadata = Tcl_DuplicateObj(masterPtr->metadata);
		    Tcl_IncrRefCount(masterPtr->metadata);
		if (Tcl_IsShared(modelPtr->metadata)) {
		    Tcl_DecrRefCount(modelPtr->metadata);
		    modelPtr->metadata = Tcl_DuplicateObj(modelPtr->metadata);
		    Tcl_IncrRefCount(modelPtr->metadata);
		}

		if (Tcl_DictObjFirst(interp, metadataOutObj, &search, &key,
			&value, &done) != TCL_OK) {
		    goto errorExit;
		}
		for (; !done ; Tcl_DictObjNext(&search, &key, &value, &done)) {
		    Tcl_DictObjPut(interp, masterPtr->metadata, key, value);
		    Tcl_DictObjPut(interp, modelPtr->metadata, key, value);
		}
	    }
	}
    }

    /*
     * Enforce a reasonable value for gamma.
     */

    if (masterPtr->gamma <= 0) {
	masterPtr->gamma = 1.0;
    if (modelPtr->gamma <= 0) {
	modelPtr->gamma = 1.0;
    }

    if ((masterPtr->gamma != oldGamma)
	    || (masterPtr->palette != oldPaletteString)) {
	masterPtr->flags |= IMAGE_CHANGED;
    if ((modelPtr->gamma != oldGamma)
	    || (modelPtr->palette != oldPaletteString)) {
	modelPtr->flags |= IMAGE_CHANGED;
    }

    /*
     * Cycle through all of the instances of this image, regenerating the
     * information for each instance. Then force the image to be redisplayed
     * everywhere that it is used.
     */

    for (instancePtr = masterPtr->instancePtr; instancePtr != NULL;
    for (instancePtr = modelPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	TkImgPhotoConfigureInstance(instancePtr);
    }

    /*
     * Inform the generic image code that the image has (potentially) changed.
     */

    Tk_ImageChanged(masterPtr->tkMaster, 0, 0, masterPtr->width,
	    masterPtr->height, masterPtr->width, masterPtr->height);
    masterPtr->flags &= ~IMAGE_CHANGED;
    Tk_ImageChanged(modelPtr->tkModel, 0, 0, modelPtr->width,
	    modelPtr->height, modelPtr->width, modelPtr->height);
    modelPtr->flags &= ~IMAGE_CHANGED;

    if (oldData != NULL) {
	Tcl_DecrRefCount(oldData);
    }
    if (oldFormat != NULL) {
	Tcl_DecrRefCount(oldFormat);
    }
    if (metadataOutObj != NULL) {
	Tcl_DecrRefCount(metadataOutObj);
    }

    ToggleComplexAlphaIfNeeded(masterPtr);
    ToggleComplexAlphaIfNeeded(modelPtr);

    return TCL_OK;

  errorExit:
    if (oldData != NULL) {
	Tcl_DecrRefCount(oldData);
    }
2369
2370
2371
2372
2373
2374
2375
2376

2377
2378
2379
2380
2381
2382
2383

2384
2385
2386
2387
2388
2389
2390
2368
2369
2370
2371
2372
2373
2374

2375
2376
2377
2378
2379
2380
2381

2382
2383
2384
2385
2386
2387
2388
2389







-
+






-
+







 *	partially transparent pixels exist, which requires blending instead of
 *	straight copy.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	(Re)sets COMPLEX_ALPHA flag of master.
 *	(Re)sets COMPLEX_ALPHA flag of model.
 *
 *----------------------------------------------------------------------
 */

static int
ToggleComplexAlphaIfNeeded(
    PhotoMaster *mPtr)
    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;

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







-
+













-
+


-
+


-
+






-
-
-
+
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+







}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoDelete --
 *
 *	This function is called by the image code to delete the master
 *	This function is called by the image code to delete the model
 *	structure for an image.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Resources associated with the image get freed.
 *
 *----------------------------------------------------------------------
 */

static void
ImgPhotoDelete(
    ClientData masterData)	/* Pointer to PhotoMaster structure for image.
    ClientData modelData)	/* Pointer to PhotoModel structure for image.
				 * Must not have any more instances. */
{
    PhotoMaster *masterPtr = (PhotoMaster *)masterData;
    PhotoModel *modelPtr = (PhotoModel *)modelData;
    PhotoInstance *instancePtr;

    while ((instancePtr = masterPtr->instancePtr) != NULL) {
    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);
    }
    masterPtr->tkMaster = NULL;
    if (masterPtr->imageCmd != NULL) {
	Tcl_DeleteCommandFromToken(masterPtr->interp, masterPtr->imageCmd);
    modelPtr->tkModel = NULL;
    if (modelPtr->imageCmd != NULL) {
	Tcl_DeleteCommandFromToken(modelPtr->interp, modelPtr->imageCmd);
    }
    if (masterPtr->pix32 != NULL) {
	ckfree(masterPtr->pix32);
    if (modelPtr->pix32 != NULL) {
	ckfree(modelPtr->pix32);
    }
    if (masterPtr->validRegion != NULL) {
	TkDestroyRegion(masterPtr->validRegion);
    if (modelPtr->validRegion != NULL) {
	TkDestroyRegion(modelPtr->validRegion);
    }
    if (masterPtr->dataString != NULL) {
	Tcl_DecrRefCount(masterPtr->dataString);
    if (modelPtr->dataString != NULL) {
	Tcl_DecrRefCount(modelPtr->dataString);
    }
    if (masterPtr->format != NULL) {
	Tcl_DecrRefCount(masterPtr->format);
    if (modelPtr->format != NULL) {
	Tcl_DecrRefCount(modelPtr->format);
    }
    if (masterPtr->metadata != NULL) {
	Tcl_DecrRefCount(masterPtr->metadata);
    if (modelPtr->metadata != NULL) {
	Tcl_DecrRefCount(modelPtr->metadata);
    }
    Tk_FreeOptions(configSpecs, (char *) masterPtr, NULL, 0);
    ckfree(masterPtr);
    Tk_FreeOptions(configSpecs, (char *) modelPtr, NULL, 0);
    ckfree(modelPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoCmdDeletedProc --
 *
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
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







-
+


-
+

-
-
-
+
+
+

















-
+






-
+









-
-
+
+

-
-
+
+













-
-
+
+







 *	The image is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ImgPhotoCmdDeletedProc(
    ClientData clientData)	/* Pointer to PhotoMaster structure for
    ClientData clientData)	/* Pointer to PhotoModel structure for
				 * image. */
{
    PhotoMaster *masterPtr = (PhotoMaster *)clientData;
    PhotoModel *modelPtr = (PhotoModel *)clientData;

    masterPtr->imageCmd = NULL;
    if (masterPtr->tkMaster != NULL) {
	Tk_DeleteImage(masterPtr->interp, Tk_NameOfImage(masterPtr->tkMaster));
    modelPtr->imageCmd = NULL;
    if (modelPtr->tkModel != NULL) {
	Tk_DeleteImage(modelPtr->interp, Tk_NameOfImage(modelPtr->tkModel));
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoSetSize --
 *
 *	This function reallocates the image storage and instance pixmaps for a
 *	photo image, as necessary, to change the image's size to `width' x
 *	`height' pixels.
 *
 * Results:
 *	TCL_OK if successful, TCL_ERROR if failure occurred (currently just
 *	with memory allocation.)
 *
 * Side effects:
 *	Storage gets reallocated, for the master and all its instances.
 *	Storage gets reallocated, for the model and all its instances.
 *
 *----------------------------------------------------------------------
 */

static int
ImgPhotoSetSize(
    PhotoMaster *masterPtr,
    PhotoModel *modelPtr,
    int width, int height)
{
    unsigned char *newPix32 = NULL;
    int h, offset, pitch;
    unsigned char *srcPtr, *destPtr;
    XRectangle validBox, clipBox;
    TkRegion clipRegion;
    PhotoInstance *instancePtr;

    if (masterPtr->userWidth > 0) {
	width = masterPtr->userWidth;
    if (modelPtr->userWidth > 0) {
	width = modelPtr->userWidth;
    }
    if (masterPtr->userHeight > 0) {
	height = masterPtr->userHeight;
    if (modelPtr->userHeight > 0) {
	height = modelPtr->userHeight;
    }

    if (width > INT_MAX / 4) {
	/* Pitch overflows int */
	return TCL_ERROR;
    }
    pitch = width * 4;

    /*
     * Test if we're going to (re)allocate the main buffer now, so that any
     * failures will leave the photo unchanged.
     */

    if ((width != masterPtr->width) || (height != masterPtr->height)
	    || (masterPtr->pix32 == NULL)) {
    if ((width != modelPtr->width) || (height != modelPtr->height)
	    || (modelPtr->pix32 == NULL)) {
	unsigned newPixSize;

	if (pitch && height > (int)(UINT_MAX / pitch)) {
	    return TCL_ERROR;
	}
	newPixSize = height * pitch;

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







-
+








-
-
+
+

-
+















-
-
+
+











-
+





-
+






-
+








-
+




-
+



-
+


-
-
-
+
+
+







-
-
+
+

-
-
-
+
+
+

-
-
-
-
+
+
+
+



-
+





-
+







    }

    /*
     * We have to trim the valid region if it is currently larger than the new
     * image size.
     */

    TkClipBox(masterPtr->validRegion, &validBox);
    TkClipBox(modelPtr->validRegion, &validBox);
    if ((validBox.x + validBox.width > width)
	    || (validBox.y + validBox.height > height)) {
	clipBox.x = 0;
	clipBox.y = 0;
	clipBox.width = width;
	clipBox.height = height;
	clipRegion = TkCreateRegion();
	TkUnionRectWithRegion(&clipBox, clipRegion, clipRegion);
	TkIntersectRegion(masterPtr->validRegion, clipRegion,
		masterPtr->validRegion);
	TkIntersectRegion(modelPtr->validRegion, clipRegion,
		modelPtr->validRegion);
	TkDestroyRegion(clipRegion);
	TkClipBox(masterPtr->validRegion, &validBox);
	TkClipBox(modelPtr->validRegion, &validBox);
    }

    /*
     * Use the reallocated storage (allocation above) for the 32-bit image and
     * copy over valid regions. Note that this test is true precisely when the
     * allocation has already been done.
     */

    if (newPix32 != NULL) {
	/*
	 * Zero the new array. The dithering code shouldn't read the areas
	 * outside validBox, but they might be copied to another photo image
	 * or written to a file.
	 */

	if ((masterPtr->pix32 != NULL)
	    && ((width == masterPtr->width) || (width == validBox.width))) {
	if ((modelPtr->pix32 != NULL)
	    && ((width == modelPtr->width) || (width == validBox.width))) {
	    if (validBox.y > 0) {
		memset(newPix32, 0, ((size_t) validBox.y * pitch));
	    }
	    h = validBox.y + validBox.height;
	    if (h < height) {
		memset(newPix32 + h*pitch, 0, ((size_t) (height - h) * pitch));
	    }
	} else {
	    memset(newPix32, 0, ((size_t)height * pitch));
	}

	if (masterPtr->pix32 != NULL) {
	if (modelPtr->pix32 != NULL) {
	    /*
	     * Copy the common area over to the new array array and free the
	     * old array.
	     */

	    if (width == masterPtr->width) {
	    if (width == modelPtr->width) {

		/*
		 * The region to be copied is contiguous.
		 */

		offset = validBox.y * pitch;
		memcpy(newPix32 + offset, masterPtr->pix32 + offset,
		memcpy(newPix32 + offset, modelPtr->pix32 + offset,
			((size_t)validBox.height * pitch));

	    } else if ((validBox.width > 0) && (validBox.height > 0)) {
		/*
		 * Area to be copied is not contiguous - copy line by line.
		 */

		destPtr = newPix32 + (validBox.y * width + validBox.x) * 4;
		srcPtr = masterPtr->pix32 + (validBox.y * masterPtr->width
		srcPtr = modelPtr->pix32 + (validBox.y * modelPtr->width
			+ validBox.x) * 4;
		for (h = validBox.height; h > 0; h--) {
		    memcpy(destPtr, srcPtr, ((size_t)validBox.width * 4));
		    destPtr += width * 4;
		    srcPtr += masterPtr->width * 4;
		    srcPtr += modelPtr->width * 4;
		}
	    }

	    ckfree(masterPtr->pix32);
	    ckfree(modelPtr->pix32);
	}

	masterPtr->pix32 = newPix32;
	masterPtr->width = width;
	masterPtr->height = height;
	modelPtr->pix32 = newPix32;
	modelPtr->width = width;
	modelPtr->height = height;

	/*
	 * Dithering will be correct up to the end of the last pre-existing
	 * complete scanline.
	 */

	if ((validBox.x > 0) || (validBox.y > 0)) {
	    masterPtr->ditherX = 0;
	    masterPtr->ditherY = 0;
	    modelPtr->ditherX = 0;
	    modelPtr->ditherY = 0;
	} else if (validBox.width == width) {
	    if ((int) validBox.height < masterPtr->ditherY) {
		masterPtr->ditherX = 0;
		masterPtr->ditherY = validBox.height;
	    if ((int) validBox.height < modelPtr->ditherY) {
		modelPtr->ditherX = 0;
		modelPtr->ditherY = validBox.height;
	    }
	} else if ((masterPtr->ditherY > 0)
		|| ((int) validBox.width < masterPtr->ditherX)) {
	    masterPtr->ditherX = validBox.width;
	    masterPtr->ditherY = 0;
	} else if ((modelPtr->ditherY > 0)
		|| ((int) validBox.width < modelPtr->ditherX)) {
	    modelPtr->ditherX = validBox.width;
	    modelPtr->ditherY = 0;
	}
    }

    ToggleComplexAlphaIfNeeded(masterPtr);
    ToggleComplexAlphaIfNeeded(modelPtr);

    /*
     * Now adjust the sizes of the pixmaps for all of the instances.
     */

    for (instancePtr = masterPtr->instancePtr; instancePtr != NULL;
    for (instancePtr = modelPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	TkImgPhotoInstanceSetSize(instancePtr);
    }

    return TCL_OK;
}

2862
2863
2864
2865
2866
2867
2868
2869


2870
2871
2872
2873

2874

2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2861
2862
2863
2864
2865
2866
2867

2868
2869
2870
2871
2872
2873
2874

2875
2876



2877
2878
2879
2880
2881
2882
2883







-
+
+




+
-
+

-
-
-







		*imageFormatPtr = NULL;
		*oldformat = 0;
		(void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET);
		return TCL_OK;
	    }

	    /*
	     * Clear eventual set keys in the metadata object
	     * Check if driver has shared or changed the metadata Tcl object.
	     * In this case, release and recreate it.
	     */

	    if (metadataOutObj != NULL) {
		int dictSize;
		if (Tcl_IsShared(metadataOutObj)
		if (TCL_OK != Tcl_DictObjSize(interp,metadataOutObj, &dictSize)
			|| TCL_OK != Tcl_DictObjSize(interp,metadataOutObj, &dictSize)
			|| dictSize > 0) {
		    /*
		     * Driver has modified the metadata dict, so clear it
		     */
		    Tcl_DecrRefCount(metadataOutObj);
		    metadataOutObj = Tcl_NewDictObj();
		    Tcl_IncrRefCount(metadataOutObj);
		}
	    }
	}
    }
3065
3066
3067
3068
3069
3070
3071
3072


3073
3074
3075
3076

3077

3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3063
3064
3065
3066
3067
3068
3069

3070
3071
3072
3073
3074
3075
3076

3077
3078



3079
3080
3081
3082
3083
3084
3085







-
+
+




+
-
+

-
-
-







		    && formatVersion3Ptr->stringMatchProc(interp, data,
			    formatObj, metadataInObj, widthPtr, heightPtr,
			    metadataOutObj)) {
		break;
	    }

	    /*
	     * Clear eventual set keys in the metadata object
	     * Check if driver has shared or changed the metadata tcl object.
	     * In this case, release and recreate it.
	     */

	    if (metadataOutObj != NULL) {
		int dictSize;
		if (Tcl_IsShared(metadataOutObj)
		if (TCL_OK != Tcl_DictObjSize(interp,metadataOutObj, &dictSize)
			|| TCL_OK != Tcl_DictObjSize(interp,metadataOutObj, &dictSize)
			|| dictSize > 0) {
		    /*
		     * Driver has modified the metadata dict, so clear it
		     */
		    Tcl_DecrRefCount(metadataOutObj);
		    metadataOutObj = Tcl_NewDictObj();
		    Tcl_IncrRefCount(metadataOutObj);
		}
	    }
	}
    }
3141
3142
3143
3144
3145
3146
3147
3148

3149
3150
3151
3152
3153
3154
3155
3138
3139
3140
3141
3142
3143
3144

3145
3146
3147
3148
3149
3150
3151
3152







-
+








/*
 *----------------------------------------------------------------------
 *
 * Tk_FindPhoto --
 *
 *	This function is called to get an opaque handle (actually a
 *	PhotoMaster *) for a given image, which can be used in subsequent
 *	PhotoModel *) for a given image, which can be used in subsequent
 *	calls to Tk_PhotoPutBlock, etc. The `name' parameter is the name of
 *	the image.
 *
 * Results:
 *	The handle for the photo image, or NULL if there is no photo image
 *	with the name given.
 *
3163
3164
3165
3166
3167
3168
3169
3170

3171
3172
3173
3174
3175
3176
3177
3160
3161
3162
3163
3164
3165
3166

3167
3168
3169
3170
3171
3172
3173
3174







-
+







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_GetImageMasterData(interp, imageName, &typePtr);
	    Tk_GetImageModelData(interp, imageName, &typePtr);

    if ((typePtr == NULL) || (typePtr->name != tkPhotoImageType.name)) {
	return NULL;
    }
    return clientData;
}

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
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







-
+


















-
-
+
+

-
-
-
+
+
+




















-
-
-
+
+
+





-
+

-
-
+
+







    int x, int y,		/* Coordinates of the top-left pixel to be
				 * updated in the image. */
    int width, int height,	/* Dimensions of the area of the image to be
				 * updated. */
    int compRule)		/* Compositing rule to use when processing
				 * transparent pixels. */
{
    PhotoMaster *masterPtr = (PhotoMaster *) handle;
    PhotoModel *modelPtr = (PhotoModel *) handle;
    Tk_PhotoImageBlock sourceBlock;
    unsigned char *memToFree;
    int xEnd, yEnd, greenOffset, blueOffset, alphaOffset;
    int wLeft, hLeft, wCopy, hCopy, pitch;
    unsigned char *srcPtr, *srcLinePtr, *destPtr, *destLinePtr;
    int sourceIsSimplePhoto = compRule & SOURCE_IS_SIMPLE_ALPHA_PHOTO;
    XRectangle rect;

    /*
     * Zero-sized blocks never cause any changes. [Bug 3078902]
     */

    if (blockPtr->height == 0 || blockPtr->width == 0) {
	return TCL_OK;
    }

    compRule &= ~SOURCE_IS_SIMPLE_ALPHA_PHOTO;

    if ((masterPtr->userWidth != 0) && ((x + width) > masterPtr->userWidth)) {
	width = masterPtr->userWidth - x;
    if ((modelPtr->userWidth != 0) && ((x + width) > modelPtr->userWidth)) {
	width = modelPtr->userWidth - x;
    }
    if ((masterPtr->userHeight != 0)
	    && ((y + height) > masterPtr->userHeight)) {
	height = masterPtr->userHeight - y;
    if ((modelPtr->userHeight != 0)
	    && ((y + height) > modelPtr->userHeight)) {
	height = modelPtr->userHeight - y;
    }
    if ((width <= 0) || (height <= 0)) {
	return TCL_OK;
    }

    /*
     * Fix for bug e4336bef5d:
     *
     * Make a local copy of *blockPtr, as we might have to change some
     * of its fields and don't want to interfere with the caller's data.
     *
     * If source and destination are the same image, create a copy  of the
     * source data in our local sourceBlock.
     *
     * To find out, just comparing the pointers is not enough - they might have
     * different values and still point to the same block of memory. (e.g.
     * if the -from option was passed to [imageName copy])
     */
    sourceBlock = *blockPtr;
    memToFree = NULL;
    if (sourceBlock.pixelPtr >= masterPtr->pix32
	    && sourceBlock.pixelPtr <= masterPtr->pix32 + masterPtr->width
	    * masterPtr->height * 4) {
    if (sourceBlock.pixelPtr >= modelPtr->pix32
	    && sourceBlock.pixelPtr <= modelPtr->pix32 + modelPtr->width
	    * modelPtr->height * 4) {
	/*
	 * Fix 5c51be6411: avoid reading
	 *
	 *	(sourceBlock.pitch - sourceBlock.width * sourceBlock.pixelSize)
	 *
	 * bytes past the end of masterPtr->pix32[] when
	 * bytes past the end of modelPtr->pix32[] when
	 *
	 *	blockPtr->pixelPtr > (masterPtr->pix32 +
	 *		4 * masterPtr->width * masterPtr->height -
	 *	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) {
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
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







-
-
-
+
+
+









-
-
+
+




-
-
+
+

















-
+







-
-
+
+










-
+







	memToFree = sourceBlock.pixelPtr;
	memcpy(sourceBlock.pixelPtr, blockPtr->pixelPtr, cpyLen);
    }


    xEnd = x + width;
    yEnd = y + height;
    if ((xEnd > masterPtr->width) || (yEnd > masterPtr->height)) {
	if (ImgPhotoSetSize(masterPtr, MAX(xEnd, masterPtr->width),
		MAX(yEnd, masterPtr->height)) == TCL_ERROR) {
    if ((xEnd > modelPtr->width) || (yEnd > modelPtr->height)) {
	if (ImgPhotoSetSize(modelPtr, MAX(xEnd, modelPtr->width),
		MAX(yEnd, modelPtr->height)) == TCL_ERROR) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    }
	    goto errorExit;
	}
    }

    if ((y < masterPtr->ditherY) || ((y == masterPtr->ditherY)
	    && (x < masterPtr->ditherX))) {
    if ((y < modelPtr->ditherY) || ((y == modelPtr->ditherY)
	    && (x < modelPtr->ditherX))) {
	/*
	 * The dithering isn't correct past the start of this block.
	 */

	masterPtr->ditherX = x;
	masterPtr->ditherY = y;
	modelPtr->ditherX = x;
	modelPtr->ditherY = y;
    }

    /*
     * If this image block could have different red, green and blue
     * components, mark it as a color image.
     */

    greenOffset = sourceBlock.offset[1] - sourceBlock.offset[0];
    blueOffset = sourceBlock.offset[2] - sourceBlock.offset[0];
    alphaOffset = sourceBlock.offset[3];
    if ((alphaOffset >= sourceBlock.pixelSize) || (alphaOffset < 0)) {
	alphaOffset = 0;
	sourceIsSimplePhoto = 1;
    } else {
	alphaOffset -= sourceBlock.offset[0];
    }
    if ((greenOffset != 0) || (blueOffset != 0)) {
	masterPtr->flags |= COLOR_IMAGE;
	modelPtr->flags |= COLOR_IMAGE;
    }

    /*
     * Copy the data into our local 32-bit/pixel array. If we can do it with a
     * single memmove, we do.
     */

    destLinePtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4;
    pitch = masterPtr->width * 4;
    destLinePtr = modelPtr->pix32 + (y * modelPtr->width + x) * 4;
    pitch = modelPtr->width * 4;

    /*
     * Test to see if we can do the whole write in a single copy. This test is
     * probably too restrictive. We should also be able to do a memmove if
     * pixelSize == 3 and alphaOffset == 0. Maybe other cases too.
     */

    if ((sourceBlock.pixelSize == 4)
	    && (greenOffset == 1) && (blueOffset == 2) && (alphaOffset == 3)
	    && (width <= sourceBlock.width) && (height <= sourceBlock.height)
	    && ((height == 1) || ((x == 0) && (width == masterPtr->width)
	    && ((height == 1) || ((x == 0) && (width == modelPtr->width)
		&& (sourceBlock.pitch == pitch)))
	    && (compRule == TK_PHOTO_COMPOSITE_SET)) {
	memmove(destLinePtr, sourceBlock.pixelPtr + sourceBlock.offset[0],
		((size_t)height * width * 4));

	/*
	 * We know there's an alpha offset and we're setting the data, so skip
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
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







-
-
+
+








-
+

-
-
+
+





-
-
+
+














-
+





-
+


-
+




-
+







-
+






-
+





-
-
+
+







	recalculateValidRegion:
	    workRgn = TkCreateRegion();
	    rect.x = x;
	    rect.y = y;
	    rect.width = width;
	    rect.height = height;
	    TkUnionRectWithRegion(&rect, workRgn, workRgn);
	    TkSubtractRegion(masterPtr->validRegion, workRgn,
		    masterPtr->validRegion);
	    TkSubtractRegion(modelPtr->validRegion, workRgn,
		    modelPtr->validRegion);
	    TkDestroyRegion(workRgn);
	}

	/*
	 * Factorize out the main part of the building of the region data to
	 * allow for more efficient per-platform implementations. [Bug 919066]
	 */

	TkpBuildRegionFromAlphaData(masterPtr->validRegion, (unsigned) x,
	TkpBuildRegionFromAlphaData(modelPtr->validRegion, (unsigned) x,
		(unsigned) y, (unsigned) width, (unsigned) height,
		masterPtr->pix32 + (y * masterPtr->width + x) * 4 + 3,
		4, (unsigned) masterPtr->width * 4);
		modelPtr->pix32 + (y * modelPtr->width + x) * 4 + 3,
		4, (unsigned) modelPtr->width * 4);
    } else {
	rect.x = x;
	rect.y = y;
	rect.width = width;
	rect.height = height;
	TkUnionRectWithRegion(&rect, masterPtr->validRegion,
		masterPtr->validRegion);
	TkUnionRectWithRegion(&rect, modelPtr->validRegion,
		modelPtr->validRegion);
    }

    /*
     * Check if display code needs alpha blending...
     */

    if (!sourceIsSimplePhoto && (height == 1)) {
	/*
	 * Optimize the single span case if we can. This speeds up code that
	 * builds up large simple-alpha images by scan-lines or individual
	 * pixels. We don't negate COMPLEX_ALPHA in this case. [Bug 1409140]
	 * [Patch 1539990]
	 */

	if (!(masterPtr->flags & COMPLEX_ALPHA)) {
	if (!(modelPtr->flags & COMPLEX_ALPHA)) {
	    int x1;

	    for (x1=x ; x1<x+width ; x1++) {
		unsigned char newAlpha;

		destLinePtr = masterPtr->pix32 + (y*masterPtr->width + x1)*4;
		destLinePtr = modelPtr->pix32 + (y*modelPtr->width + x1)*4;
		newAlpha = destLinePtr[3];
		if (newAlpha && newAlpha != 255) {
		    masterPtr->flags |= COMPLEX_ALPHA;
		    modelPtr->flags |= COMPLEX_ALPHA;
		    break;
		}
	    }
	}
    } else if ((alphaOffset != 0) || (masterPtr->flags & COMPLEX_ALPHA)) {
    } else if ((alphaOffset != 0) || (modelPtr->flags & COMPLEX_ALPHA)) {
	/*
	 * Check for partial transparency if alpha pixels are specified, or
	 * rescan if we already knew such pixels existed. To restrict this
	 * Toggle to only checking the changed pixels requires knowing where
	 * the alpha pixels are.
	 */

	ToggleComplexAlphaIfNeeded(masterPtr);
	ToggleComplexAlphaIfNeeded(modelPtr);
    }

    /*
     * Update each instance.
     */

    Tk_DitherPhoto((Tk_PhotoHandle)masterPtr, x, y, width, height);
    Tk_DitherPhoto((Tk_PhotoHandle)modelPtr, x, y, width, height);

    /*
     * Tell the core image code that this image has changed.
     */

    Tk_ImageChanged(masterPtr->tkMaster, x, y, width, height,
	    masterPtr->width, masterPtr->height);
    Tk_ImageChanged(modelPtr->tkModel, x, y, width, height,
	    modelPtr->width, modelPtr->height);

    if (memToFree) ckfree(memToFree);

    return TCL_OK;

  errorExit:
    if (memToFree) ckfree(memToFree);
3644
3645
3646
3647
3648
3649
3650
3651

3652
3653
3654
3655
3656
3657
3658
3641
3642
3643
3644
3645
3646
3647

3648
3649
3650
3651
3652
3653
3654
3655







-
+







    int zoomX, int zoomY,	/* Zoom factors for the X and Y axes. */
    int subsampleX, int subsampleY,
				/* Subsampling factors for the X and Y
				 * axes. */
    int compRule)		/* Compositing rule to use when processing
				 * transparent pixels. */
{
    PhotoMaster *masterPtr = (PhotoMaster *) handle;
    PhotoModel *modelPtr = (PhotoModel *) handle;
    Tk_PhotoImageBlock sourceBlock;
    unsigned char *memToFree;
    int xEnd, yEnd, greenOffset, blueOffset, alphaOffset;
    int wLeft, hLeft, wCopy, hCopy, blockWid, blockHt;
    unsigned char *srcPtr, *srcLinePtr, *srcOrigPtr, *destPtr, *destLinePtr;
    int pitch, xRepeat, yRepeat, blockXSkip, blockYSkip, sourceIsSimplePhoto;
    XRectangle rect;
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
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







-
-
+
+

-
-
-
+
+
+



















-
-
-
+
+
+





-
+

-
-
+
+




















-
-
-
+
+
+









-
-
+
+




-
-
+
+

















-
+








    sourceIsSimplePhoto = compRule & SOURCE_IS_SIMPLE_ALPHA_PHOTO;
    compRule &= ~SOURCE_IS_SIMPLE_ALPHA_PHOTO;

    if (zoomX <= 0 || zoomY <= 0) {
	return TCL_OK;
    }
    if ((masterPtr->userWidth != 0) && ((x + width) > masterPtr->userWidth)) {
	width = masterPtr->userWidth - x;
    if ((modelPtr->userWidth != 0) && ((x + width) > modelPtr->userWidth)) {
	width = modelPtr->userWidth - x;
    }
    if ((masterPtr->userHeight != 0)
	    && ((y + height) > masterPtr->userHeight)) {
	height = masterPtr->userHeight - y;
    if ((modelPtr->userHeight != 0)
	    && ((y + height) > modelPtr->userHeight)) {
	height = modelPtr->userHeight - y;
    }
    if (width <= 0 || height <= 0) {
	return TCL_OK;
    }

    /*
     * Fix for Bug e4336bef5d:
     * Make a local copy of *blockPtr, as we might have to change some
     * of its fields and don't want to interfere with the caller's data.
     *
     * If source and destination are the same image, create a copy  of the
     * source data in our local sourceBlock.
     *
     * To find out, just comparing the pointers is not enough - they might have
     * different values and still point to the same block of memory. (e.g.
     * if the -from option was passed to [imageName copy])
     */
    sourceBlock = *blockPtr;
    memToFree = NULL;
    if (sourceBlock.pixelPtr >= masterPtr->pix32
	    && sourceBlock.pixelPtr <= masterPtr->pix32 + masterPtr->width
	    * masterPtr->height * 4) {
    if (sourceBlock.pixelPtr >= modelPtr->pix32
	    && sourceBlock.pixelPtr <= modelPtr->pix32 + modelPtr->width
	    * modelPtr->height * 4) {
	/*
	 * Fix 5c51be6411: avoid reading
	 *
	 *	(sourceBlock.pitch - sourceBlock.width * sourceBlock.pixelSize)
	 *
	 * bytes past the end of masterPtr->pix32[] when
	 * bytes past the end of modelPtr->pix32[] when
	 *
	 *	blockPtr->pixelPtr > (masterPtr->pix32 +
	 *		4 * masterPtr->width * masterPtr->height -
	 *	blockPtr->pixelPtr > (modelPtr->pix32 +
	 *		4 * modelPtr->width * modelPtr->height -
	 *		sourceBlock.height * sourceBlock.pitch)
	 */
	unsigned int cpyLen = (sourceBlock.height - 1) * sourceBlock.pitch +
		sourceBlock.width * sourceBlock.pixelSize;

	sourceBlock.pixelPtr = (unsigned char *)attemptckalloc(cpyLen);
	if (sourceBlock.pixelPtr == NULL) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    }
	    return TCL_ERROR;
	}
	memToFree = sourceBlock.pixelPtr;
	memcpy(sourceBlock.pixelPtr, blockPtr->pixelPtr, cpyLen);
    }

    xEnd = x + width;
    yEnd = y + height;
    if ((xEnd > masterPtr->width) || (yEnd > masterPtr->height)) {
	if (ImgPhotoSetSize(masterPtr, MAX(xEnd, masterPtr->width),
		MAX(yEnd, masterPtr->height)) == TCL_ERROR) {
    if ((xEnd > modelPtr->width) || (yEnd > modelPtr->height)) {
	if (ImgPhotoSetSize(modelPtr, MAX(xEnd, modelPtr->width),
		MAX(yEnd, modelPtr->height)) == TCL_ERROR) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    }
	    goto errorExit;
	}
    }

    if ((y < masterPtr->ditherY) || ((y == masterPtr->ditherY)
	    && (x < masterPtr->ditherX))) {
    if ((y < modelPtr->ditherY) || ((y == modelPtr->ditherY)
	    && (x < modelPtr->ditherX))) {
	/*
	 * The dithering isn't correct past the start of this block.
	 */

	masterPtr->ditherX = x;
	masterPtr->ditherY = y;
	modelPtr->ditherX = x;
	modelPtr->ditherY = y;
    }

    /*
     * If this image block could have different red, green and blue
     * components, mark it as a color image.
     */

    greenOffset = sourceBlock.offset[1] - sourceBlock.offset[0];
    blueOffset = sourceBlock.offset[2] - sourceBlock.offset[0];
    alphaOffset = sourceBlock.offset[3];
    if ((alphaOffset >= sourceBlock.pixelSize) || (alphaOffset < 0)) {
	alphaOffset = 0;
	sourceIsSimplePhoto = 1;
    } else {
	alphaOffset -= sourceBlock.offset[0];
    }
    if ((greenOffset != 0) || (blueOffset != 0)) {
	masterPtr->flags |= COLOR_IMAGE;
	modelPtr->flags |= COLOR_IMAGE;
    }

    /*
     * Work out what area the pixel data in the block expands to after
     * subsampling and zooming.
     */

3795
3796
3797
3798
3799
3800
3801
3802

3803
3804
3805
3806
3807
3808
3809
3810
3811

3812
3813
3814
3815
3816
3817
3818
3792
3793
3794
3795
3796
3797
3798

3799
3800
3801
3802
3803
3804
3805
3806
3807

3808
3809
3810
3811
3812
3813
3814
3815







-
+








-
+







	blockHt = ((sourceBlock.height - subsampleY - 1) / -subsampleY) * zoomY;
    }

    /*
     * Copy the data into our local 32-bit/pixel array.
     */

    destLinePtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4;
    destLinePtr = modelPtr->pix32 + (y * modelPtr->width + x) * 4;
    srcOrigPtr = sourceBlock.pixelPtr + sourceBlock.offset[0];
    if (subsampleX < 0) {
	srcOrigPtr += (sourceBlock.width - 1) * sourceBlock.pixelSize;
    }
    if (subsampleY < 0) {
	srcOrigPtr += (sourceBlock.height - 1) * sourceBlock.pitch;
    }

    pitch = masterPtr->width * 4;
    pitch = modelPtr->width * 4;
    for (hLeft = height; hLeft > 0; ) {
	hCopy = MIN(hLeft, blockHt);
	hLeft -= hCopy;
	yRepeat = zoomY;
	srcLinePtr = srcOrigPtr;
	for (; hCopy > 0; --hCopy) {
	    destPtr = destLinePtr;
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
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







-
-
+
+



-
+

-
-
+
+





-
-
+
+












-
+


-
+



-
+


-
+






-
+






-
+





-
-
+
+

















-
+






-
+







-
+





-
+






-
+









-
-
-
+
+
+



-
+


-
+





-
-
+
+







-
-
-
-
-
+
+
+
+
+







	    TkRegion workRgn = TkCreateRegion();

	    rect.x = x;
	    rect.y = y;
	    rect.width = width;
	    rect.height = 1;
	    TkUnionRectWithRegion(&rect, workRgn, workRgn);
	    TkSubtractRegion(masterPtr->validRegion, workRgn,
		    masterPtr->validRegion);
	    TkSubtractRegion(modelPtr->validRegion, workRgn,
		    modelPtr->validRegion);
	    TkDestroyRegion(workRgn);
	}

	TkpBuildRegionFromAlphaData(masterPtr->validRegion,
	TkpBuildRegionFromAlphaData(modelPtr->validRegion,
		(unsigned)x, (unsigned)y, (unsigned)width, (unsigned)height,
		&masterPtr->pix32[(y * masterPtr->width + x) * 4 + 3], 4,
		(unsigned) masterPtr->width * 4);
		&modelPtr->pix32[(y * modelPtr->width + x) * 4 + 3], 4,
		(unsigned) modelPtr->width * 4);
    } else {
	rect.x = x;
	rect.y = y;
	rect.width = width;
	rect.height = height;
	TkUnionRectWithRegion(&rect, masterPtr->validRegion,
		masterPtr->validRegion);
	TkUnionRectWithRegion(&rect, modelPtr->validRegion,
		modelPtr->validRegion);
    }

    /*
     * Check if display code needs alpha blending...
     */

    if (!sourceIsSimplePhoto && (width == 1) && (height == 1)) {
	/*
	 * Optimize the single pixel case if we can. This speeds up code that
	 * builds up large simple-alpha images by single pixels. We don't
	 * negate COMPLEX_ALPHA in this case. [Bug 1409140]
	 */
	if (!(masterPtr->flags & COMPLEX_ALPHA)) {
	if (!(modelPtr->flags & COMPLEX_ALPHA)) {
	    unsigned char newAlpha;

	    destLinePtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4;
	    destLinePtr = modelPtr->pix32 + (y * modelPtr->width + x) * 4;
	    newAlpha = destLinePtr[3];

	    if (newAlpha && newAlpha != 255) {
		masterPtr->flags |= COMPLEX_ALPHA;
		modelPtr->flags |= COMPLEX_ALPHA;
	    }
	}
    } else if ((alphaOffset != 0) || (masterPtr->flags & COMPLEX_ALPHA)) {
    } else if ((alphaOffset != 0) || (modelPtr->flags & COMPLEX_ALPHA)) {
	/*
	 * Check for partial transparency if alpha pixels are specified, or
	 * rescan if we already knew such pixels existed. To restrict this
	 * Toggle to only checking the changed pixels requires knowing where
	 * the alpha pixels are.
	 */
	ToggleComplexAlphaIfNeeded(masterPtr);
	ToggleComplexAlphaIfNeeded(modelPtr);
    }

    /*
     * Update each instance.
     */

    Tk_DitherPhoto((Tk_PhotoHandle) masterPtr, x, y, width, height);
    Tk_DitherPhoto((Tk_PhotoHandle) modelPtr, x, y, width, height);

    /*
     * Tell the core image code that this image has changed.
     */

    Tk_ImageChanged(masterPtr->tkMaster, x, y, width, height, masterPtr->width,
	    masterPtr->height);
    Tk_ImageChanged(modelPtr->tkModel, x, y, width, height, modelPtr->width,
	    modelPtr->height);

    if (memToFree) ckfree(memToFree);

    return TCL_OK;

  errorExit:
    if (memToFree) ckfree(memToFree);

    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_DitherPhoto --
 *
 *	This function is called to update an area of each instance's pixmap by
 *	dithering the corresponding area of the image master.
 *	dithering the corresponding area of the image model.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The pixmap of each instance of this image gets updated. The fields in
 *	*masterPtr indicating which area of the image is correctly dithered
 *	*modelPtr indicating which area of the image is correctly dithered
 *	get updated.
 *
 *----------------------------------------------------------------------
 */

void
Tk_DitherPhoto(
    Tk_PhotoHandle photo,	/* Image master whose instances are to be
    Tk_PhotoHandle photo,	/* Image model whose instances are to be
				 * updated. */
    int x, int y,		/* Coordinates of the top-left pixel in the
				 * area to be dithered. */
    int width, int height)	/* Dimensions of the area to be dithered. */
{
    PhotoMaster *masterPtr = (PhotoMaster *) photo;
    PhotoModel *modelPtr = (PhotoModel *) photo;
    PhotoInstance *instancePtr;

    if ((width <= 0) || (height <= 0)) {
	return;
    }

    for (instancePtr = masterPtr->instancePtr; instancePtr != NULL;
    for (instancePtr = modelPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	TkImgDitherInstance(instancePtr, x, y, width, height);
    }

    /*
     * Work out whether this block will be correctly dithered and whether it
     * will extend the correctly dithered region.
     */

    if (((y < masterPtr->ditherY)
	    || ((y == masterPtr->ditherY) && (x <= masterPtr->ditherX)))
	    && ((y + height) > (masterPtr->ditherY))) {
    if (((y < modelPtr->ditherY)
	    || ((y == modelPtr->ditherY) && (x <= modelPtr->ditherX)))
	    && ((y + height) > (modelPtr->ditherY))) {
	/*
	 * This block starts inside (or immediately after) the correctly
	 * dithered region, so the first scan line at least will be right.
	 * Furthermore this block extends into scanline masterPtr->ditherY.
	 * Furthermore this block extends into scanline modelPtr->ditherY.
	 */

	if ((x == 0) && (width == masterPtr->width)) {
	if ((x == 0) && (width == modelPtr->width)) {
	    /*
	     * We are doing the full width, therefore the dithering will be
	     * correct to the end.
	     */

	    masterPtr->ditherX = 0;
	    masterPtr->ditherY = y + height;
	    modelPtr->ditherX = 0;
	    modelPtr->ditherY = y + height;
	} else {
	    /*
	     * We are doing partial scanlines, therefore the
	     * correctly-dithered region will be extended by at most one scan
	     * line.
	     */

	    if (x <= masterPtr->ditherX) {
		masterPtr->ditherX = x + width;
		if (masterPtr->ditherX >= masterPtr->width) {
		    masterPtr->ditherX = 0;
		    masterPtr->ditherY++;
	    if (x <= modelPtr->ditherX) {
		modelPtr->ditherX = x + width;
		if (modelPtr->ditherX >= modelPtr->width) {
		    modelPtr->ditherX = 0;
		    modelPtr->ditherY++;
		}
	    }
	}
    }
}

/*
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
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







-
+


-
-
+
+





-
-
+
+

-
+






-
-
-
+
+
+








-
-
+
+







 *----------------------------------------------------------------------
 */

void
Tk_PhotoBlank(
    Tk_PhotoHandle handle)	/* Handle for the image to be blanked. */
{
    PhotoMaster *masterPtr = (PhotoMaster *) handle;
    PhotoModel *modelPtr = (PhotoModel *) handle;
    PhotoInstance *instancePtr;

    masterPtr->ditherX = masterPtr->ditherY = 0;
    masterPtr->flags = 0;
    modelPtr->ditherX = modelPtr->ditherY = 0;
    modelPtr->flags = 0;

    /*
     * The image has valid data nowhere.
     */

    if (masterPtr->validRegion != NULL) {
	TkDestroyRegion(masterPtr->validRegion);
    if (modelPtr->validRegion != NULL) {
	TkDestroyRegion(modelPtr->validRegion);
    }
    masterPtr->validRegion = TkCreateRegion();
    modelPtr->validRegion = TkCreateRegion();

    /*
     * Clear out the 32-bit pixel storage array. Clear out the dithering error
     * arrays for each instance.
     */

    memset(masterPtr->pix32, 0,
	    ((size_t)masterPtr->width * masterPtr->height * 4));
    for (instancePtr = masterPtr->instancePtr; instancePtr != NULL;
    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(masterPtr->tkMaster, 0, 0, masterPtr->width,
	    masterPtr->height, masterPtr->width, masterPtr->height);
    Tk_ImageChanged(modelPtr->tkModel, 0, 0, modelPtr->width,
	    modelPtr->height, modelPtr->width, modelPtr->height);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoExpand --
 *
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
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







-
+

-
-
+
+

-
-
+
+

-
-
-
+
+
+







-
-
+
+







int
Tk_PhotoExpand(
    Tcl_Interp *interp,		/* Interpreter for passing back error
				 * messages, or NULL. */
    Tk_PhotoHandle handle,	/* Handle for the image to be expanded. */
    int width, int height)	/* Desired minimum dimensions of the image. */
{
    PhotoMaster *masterPtr = (PhotoMaster *) handle;
    PhotoModel *modelPtr = (PhotoModel *) handle;

    if (width <= masterPtr->width) {
	width = masterPtr->width;
    if (width <= modelPtr->width) {
	width = modelPtr->width;
    }
    if (height <= masterPtr->height) {
	height = masterPtr->height;
    if (height <= modelPtr->height) {
	height = modelPtr->height;
    }
    if ((width != masterPtr->width) || (height != masterPtr->height)) {
	if (ImgPhotoSetSize(masterPtr, MAX(width, masterPtr->width),
		MAX(height, masterPtr->height)) == TCL_ERROR) {
    if ((width != modelPtr->width) || (height != modelPtr->height)) {
	if (ImgPhotoSetSize(modelPtr, MAX(width, modelPtr->width),
		MAX(height, modelPtr->height)) == TCL_ERROR) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    }
	    return TCL_ERROR;
	}
	Tk_ImageChanged(masterPtr->tkMaster, 0, 0, 0, 0, masterPtr->width,
		masterPtr->height);
	Tk_ImageChanged(modelPtr->tkModel, 0, 0, 0, 0, modelPtr->width,
		modelPtr->height);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
4172
4173
4174
4175
4176
4177
4178
4179

4180
4181
4182


4183
4184
4185
4186
4187
4188
4189
4169
4170
4171
4172
4173
4174
4175

4176
4177


4178
4179
4180
4181
4182
4183
4184
4185
4186







-
+

-
-
+
+







Tk_PhotoGetSize(
    Tk_PhotoHandle handle,	/* Handle for the image whose dimensions are
				 * requested. */
    int *widthPtr, int *heightPtr)
				/* The dimensions of the image are returned
				 * here. */
{
    PhotoMaster *masterPtr = (PhotoMaster *) handle;
    PhotoModel *modelPtr = (PhotoModel *) handle;

    *widthPtr = masterPtr->width;
    *heightPtr = masterPtr->height;
    *widthPtr = modelPtr->width;
    *heightPtr = modelPtr->height;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoSetSize --
 *
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
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







-
+

-
-
-
-
+
+
+
+







-
-
+
+







Tk_PhotoSetSize(
    Tcl_Interp *interp,		/* Interpreter for passing back error
				 * messages, or NULL. */
    Tk_PhotoHandle handle,	/* Handle for the image whose size is to be
				 * set. */
    int width, int height)	/* New dimensions for the image. */
{
    PhotoMaster *masterPtr = (PhotoMaster *) handle;
    PhotoModel *modelPtr = (PhotoModel *) handle;

    masterPtr->userWidth = width;
    masterPtr->userHeight = height;
    if (ImgPhotoSetSize(masterPtr, ((width > 0) ? width: masterPtr->width),
	    ((height > 0) ? height: masterPtr->height)) == TCL_ERROR) {
    modelPtr->userWidth = width;
    modelPtr->userHeight = height;
    if (ImgPhotoSetSize(modelPtr, ((width > 0) ? width: modelPtr->width),
	    ((height > 0) ? height: modelPtr->height)) == TCL_ERROR) {
	if (interp != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
	    Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	}
	return TCL_ERROR;
    }
    Tk_ImageChanged(masterPtr->tkMaster, 0, 0, 0, 0,
	    masterPtr->width, masterPtr->height);
    Tk_ImageChanged(modelPtr->tkModel, 0, 0, 0, 0,
	    modelPtr->width, modelPtr->height);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetPhotoValidRegion --
4247
4248
4249
4250
4251
4252
4253
4254

4255
4256

4257
4258
4259
4260
4261
4262
4263
4244
4245
4246
4247
4248
4249
4250

4251
4252

4253
4254
4255
4256
4257
4258
4259
4260







-
+

-
+







 */

TkRegion
TkPhotoGetValidRegion(
    Tk_PhotoHandle handle)	/* Handle for the image whose valid region is
				 * to obtained. */
{
    PhotoMaster *masterPtr = (PhotoMaster *) handle;
    PhotoModel *modelPtr = (PhotoModel *) handle;

    return masterPtr->validRegion;
    return modelPtr->validRegion;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgGetPhoto --
 *
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
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







-
+









-
+





-
+







 *	None.
 *
 *----------------------------------------------------------------------
 */

static char *
ImgGetPhoto(
    PhotoMaster *masterPtr,	/* Handle for the photo image from which image
    PhotoModel *modelPtr,	/* Handle for the photo image from which image
				 * data is desired. */
    Tk_PhotoImageBlock *blockPtr,
				/* Information about the address and layout of
				 * the image data is returned here. */
    struct SubcommandOptions *optPtr)
{
    unsigned char *pixelPtr;
    int x, y, greenOffset, blueOffset, alphaOffset;

    Tk_PhotoGetImage((Tk_PhotoHandle) masterPtr, blockPtr);
    Tk_PhotoGetImage((Tk_PhotoHandle) modelPtr, blockPtr);
    blockPtr->pixelPtr += optPtr->fromY * blockPtr->pitch
	    + optPtr->fromX * blockPtr->pixelSize;
    blockPtr->width = optPtr->fromX2 - optPtr->fromX;
    blockPtr->height = optPtr->fromY2 - optPtr->fromY;

    if (!(masterPtr->flags & COLOR_IMAGE) &&
    if (!(modelPtr->flags & COLOR_IMAGE) &&
	    (!(optPtr->options & OPT_BACKGROUND)
	    || ((optPtr->background->red == optPtr->background->green)
	    && (optPtr->background->red == optPtr->background->blue)))) {
	blockPtr->offset[0] = blockPtr->offset[1] = blockPtr->offset[2];
    }
    alphaOffset = 0;
    for (y = 0; y < blockPtr->height; y++) {
4319
4320
4321
4322
4323
4324
4325
4326

4327
4328
4329
4330
4331
4332
4333
4316
4317
4318
4319
4320
4321
4322

4323
4324
4325
4326
4327
4328
4329
4330







-
+







    if (!alphaOffset) {
	blockPtr->offset[3]= -1; /* Tell caller alpha need not be read */
    }
    greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
    blueOffset = blockPtr->offset[2] - blockPtr->offset[0];
    if (((optPtr->options & OPT_BACKGROUND) && alphaOffset) ||
	    ((optPtr->options & OPT_GRAYSCALE) && (greenOffset||blueOffset))) {
	int newPixelSize,x,y;
	int newPixelSize;
	unsigned char *srcPtr, *destPtr;
	char *data;

	newPixelSize = (!(optPtr->options & OPT_BACKGROUND) && alphaOffset)
		? 2 : 1;
	if ((greenOffset||blueOffset) && !(optPtr->options & OPT_GRAYSCALE)) {
	    newPixelSize += 2;
4472
4473
4474
4475
4476
4477
4478
4479

4480
4481
4482
4483
4484




4485
4486
4487
4488
4489
4490
4491
4469
4470
4471
4472
4473
4474
4475

4476
4477




4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488







-
+

-
-
-
-
+
+
+
+







Tk_PhotoGetImage(
    Tk_PhotoHandle handle,	/* Handle for the photo image from which image
				 * data is desired. */
    Tk_PhotoImageBlock *blockPtr)
				/* Information about the address and layout of
				 * the image data is returned here. */
{
    PhotoMaster *masterPtr = (PhotoMaster *) handle;
    PhotoModel *modelPtr = (PhotoModel *) handle;

    blockPtr->pixelPtr = masterPtr->pix32;
    blockPtr->width = masterPtr->width;
    blockPtr->height = masterPtr->height;
    blockPtr->pitch = masterPtr->width * 4;
    blockPtr->pixelPtr = modelPtr->pix32;
    blockPtr->width = modelPtr->width;
    blockPtr->height = modelPtr->height;
    blockPtr->pitch = modelPtr->width * 4;
    blockPtr->pixelSize = 4;
    blockPtr->offset[0] = 0;
    blockPtr->offset[1] = 1;
    blockPtr->offset[2] = 2;
    blockPtr->offset[3] = 3;
    return 1;
}
4526
4527
4528
4529
4530
4531
4532
4533

4534
4535
4536
4537
4538
4539
4540
4523
4524
4525
4526
4527
4528
4529

4530
4531
4532
4533
4534
4535
4536
4537







-
+







}

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 *----------------------------------------------------------------------
 */
4567
4568
4569
4570
4571
4572
4573
4574

4575
4576
4577
4578
4579
4580
4581
4564
4565
4566
4567
4568
4569
4570

4571
4572
4573
4574
4575
4576
4577
4578







-
+








/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 *----------------------------------------------------------------------
 */

Changes to generic/tkImgPhoto.h.

1
2
3
4
5
6
7
8
9




10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

30
31
32
33

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
1
2
3
4
5




6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51







52
53
54
55
56
57
58





-
-
-
-
+
+
+
+




















+



-
+

















-
-
-
-
-
-
-







/*
 * tkImgPhoto.h --
 *
 *	Declarations for images of type "photo" for Tk.
 *
 * Copyright (c) 1994 The Australian National University.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 2002-2008 Donal K. Fellows
 * Copyright (c) 2003 ActiveState Corporation.
 * Copyright © 1994 The Australian National University.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 2002-2008 Donal K. Fellows
 * Copyright © 2003 ActiveState Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * Author: Paul Mackerras ([email protected]),
 *	   Department of Computer Science,
 *	   Australian National University.
 */

#include "tkInt.h"
#ifdef _WIN32
#include "tkWinInt.h"
#elif defined(__CYGWIN__)
#include "tkUnixInt.h"
#endif

/*
 * Forward declarations of the structures we define.
 */

#define PhotoMaster PhotoModel
typedef struct ColorTableId	ColorTableId;
typedef struct ColorTable	ColorTable;
typedef struct PhotoInstance	PhotoInstance;
typedef struct PhotoMaster	PhotoMaster;
typedef struct PhotoModel	PhotoModel;

/*
 * A signed 8-bit integral type. If chars are unsigned and the compiler isn't
 * an ANSI one, then we have to use short instead (which wastes space) to get
 * signed behavior.
 */

#if defined(__STDC__) || defined(_AIX)
    typedef signed char schar;
#else
#   ifndef __CHAR_UNSIGNED__
	typedef char schar;
#   else
	typedef short schar;
#   endif
#endif

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

105
106
107
108
109
110
111
112

113
114
115


116
117
118
119
120
121
122
99
100
101
102
103
104
105

106
107


108
109
110
111
112
113
114
115
116







-
+

-
-
+
+







				 * 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. */

    pixel redValues[256];	/* Maps 8-bit values of red intensity to a
    unsigned redValues[256];	/* Maps 8-bit values of red intensity to a
				 * pixel value or index in pixelMap. */
    pixel greenValues[256];	/* Ditto for green intensity. */
    pixel blueValues[256];	/* Ditto for blue intensity. */
    unsigned greenValues[256];	/* Ditto for green intensity. */
    unsigned blueValues[256];	/* Ditto for blue intensity. */
    unsigned long *pixelMap;	/* Actual pixel values allocated. */

    unsigned char colorQuant[3][256];
				/* Maps 8-bit intensities to quantized
				 * intensities. The first index is 0 for red,
				 * 1 for green, 2 for blue. */
};
140
141
142
143
144
145
146
147

148
149
150
151


152
153
154
155
156
157
158
134
135
136
137
138
139
140

141
142
143


144
145
146
147
148
149
150
151
152







-
+


-
-
+
+








#define BLACK_AND_WHITE		1
#define COLOR_WINDOW		2
#define DISPOSE_PENDING		4
#define MAP_COLORS		8

/*
 * Definition of the data associated with each photo image master.
 * Definition of the data associated with each photo image model.
 */

struct PhotoMaster {
    Tk_ImageMaster tkMaster;	/* Tk's token for image master. NULL means the
struct PhotoModel {
    Tk_ImageModel tkModel;	/* Tk's token for image model. NULL means the
				 * image is being deleted. */
    Tcl_Interp *interp;		/* Interpreter associated with the application
				 * using this image. */
    Tcl_Command imageCmd;	/* Token for image command (used to delete it
				 * when the image goes away). NULL means the
				 * image command has already been deleted. */
    int	flags;			/* Sundry flags, defined below. */
169
170
171
172
173
174
175
176

177
178
179
180

181
182
183
184
185
186
187
163
164
165
166
167
168
169

170
171
172
173

174
175
176
177
178
179
180
181







-
+



-
+







				 * image file */
    unsigned char *pix32;	/* Local storage for 32-bit image. */
    int ditherX, ditherY;	/* Location of first incorrectly dithered
				 * pixel in image. */
    TkRegion validRegion;	/* Tk region indicating which parts of the
				 * image have valid image data. */
    PhotoInstance *instancePtr;	/* First in the list of instances associated
				 * with this master. */
				 * with this model. */
};

/*
 * Bit definitions for the flags field of a PhotoMaster.
 * Bit definitions for the flags field of a PhotoModel.
 * COLOR_IMAGE:			1 means that the image has different color
 *				components.
 * IMAGE_CHANGED:		1 means that the instances of this image need
 *				to be redithered.
 * COMPLEX_ALPHA:		1 means that the instances of this image have
 *				alpha values that aren't 0 or 255, and so need
 *				the copy-merge-replace renderer .
200
201
202
203
204
205
206
207

208
209
210
211
212

213
214
215
216
217
218
219
220
221

222
223
224
225
226
227
228
194
195
196
197
198
199
200

201
202
203
204
205

206
207
208
209
210
211
212
213
214

215
216
217
218
219
220
221
222







-
+




-
+








-
+








/*
 * 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 {
    PhotoMaster *masterPtr;	/* Pointer to master for image. */
    PhotoModel *modelPtr;	/* Pointer to model for image. */
    Display *display;		/* Display for windows using this instance. */
    Colormap colormap;		/* The image may only be used in windows with
				 * this particular colormap. */
    PhotoInstance *nextPtr;	/* Pointer to the next instance in the list of
				 * instances associated with this master. */
				 * instances associated with this model. */
#if TCL_MAJOR_VERSION > 8
    size_t refCount;		/* Number of instances using this structure. */
#else
    unsigned int refCount;	/* Number of instances using this structure. */
#endif
    Tk_Uid palette;		/* Palette for these particular instances. */
    double gamma;		/* Gamma value for these instances. */
    Tk_Uid defaultPalette;	/* Default palette to use if a palette is not
				 * specified for the master. */
				 * specified for the model. */
    ColorTable *colorTablePtr;	/* Pointer to information about colors
				 * allocated for image display in windows like
				 * this one. */
    Pixmap pixels;		/* X pixmap containing dithered image. */
    int width, height;		/* Dimensions of the pixmap. */
    schar *error;		/* Error image, used in dithering. */
    XImage *imagePtr;		/* Image structure for converted pixels. */

Changes to 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
1
2
3
4
5



6
7
8
9
10
11
12
13
14

15

16
17
18
19
20
21
22





-
-
-
+
+
+
+





-
+
-







/*
 * tkImgSVGnano.c
 *
 *	A photo file handler for SVG files.
 *
 * Copyright (c) 2013-14 Mikko Mononen [email protected]
 * Copyright (c) 2018 Christian Gollwitzer [email protected]
 * Copyright (c) 2018 Rene Zaumseil [email protected]
 * Copyright © 2013-14 Mikko Mononen [email protected]
 * Copyright © 2018 Christian Gollwitzer [email protected]
 * Copyright © 2018 Christian Werner https://www.androwish.org/
 * Copyright © 2018 Rene Zaumseil [email protected]
 *
 * 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 and the tcl extension files from
 * https://github.com/memononen/nanosvg
 * https://github.com/auriocus/tksvg
 *
 */

#include "tkInt.h"
#define NANOSVG_malloc	ckalloc
#define NANOSVG_realloc	ckrealloc
#define NANOSVG_free	ckfree
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







+
+







     */
    ClientData dataOrChan;
    Tcl_DString formatString;
    NSVGimage *nsvgImage;
    RastOpts ropts;
} NSVGcache;

static const void *	MemMem(const void *haystack, size_t haysize,
			       const void *needle, size_t needlen);
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);
97
98
99
100
101
102
103








































104
105
106
107
108
109
110
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152







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







    NULL,			/* stringWriteProc */
    NULL
};

/*
 *----------------------------------------------------------------------
 *
 * MemMem --
 *
 *	Like strstr() but operating on memory buffers with sizes.
 *
 *----------------------------------------------------------------------
 */

static const void *
MemMem(const void *haystack, size_t haylen,
       const void *needle, size_t needlen)
{
    const void *hayend, *second, *p;
    unsigned char first;

    if ((needlen <= 0) || (haylen < needlen)) {
	return NULL;
    }
    hayend = (const void *) ((char *) haystack + haylen - needlen);
    first = ((char *) needle)[0];
    second = (const void *) ((char *) needle + 1);
    needlen -= 1;
    while (haystack < hayend) {
	p = memchr(haystack, first, (char *) hayend - (char *) haystack);
	if (p == NULL) {
	    break;
	}
	if (needlen == 0) {
	    return p;
	}
	haystack = (const void *) ((char *) p + 1);
	if (memcmp(second, haystack, needlen) == 0) {
	    return p;
	}
    }
    return 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,
128
129
130
131
132
133
134
135













136
137
138
139
140

141
142
143
144
145
146
147
170
171
172
173
174
175
176

177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

194
195
196
197
198
199
200
201







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




-
+







    Tcl_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) {
    if (Tcl_ReadChars(chan, dataObj, 4096, 0) == TCL_IO_FAILURE) {
	/* in case of an error reading the file */
	Tcl_DecrRefCount(dataObj);
	return 0;
    }
    data = Tcl_GetStringFromObj(dataObj, &length);
    /* should have a '<svg' and a '>' in the first 4k */
    if ((memchr(data, '>', length) == NULL) ||
	(MemMem(data, length, "<svg", 4) == NULL)) {
	Tcl_DecrRefCount(dataObj);
	return 0;
    }
    if (!Tcl_Eof(chan) && (Tcl_ReadChars(chan, dataObj, -1, 1) == TCL_IO_FAILURE)) {
	/* in case of an error reading the file */
	Tcl_DecrRefCount(dataObj);
	return 0;
    }
    data = TkGetStringFromObj(dataObj, &length);
    data = Tcl_GetStringFromObj(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;
196
197
198
199
200
201
202
203

204
205
206
207
208
209
210
250
251
252
253
254
255
256

257
258
259
260
261
262
263
264







-
+







	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);
	data = Tcl_GetStringFromObj(dataObj, &length);
	nsvgImage = ParseSVGWithOptions(interp, data, length, formatObj,
			    &ropts);
	Tcl_DecrRefCount(dataObj);
	if (nsvgImage == NULL) {
	    return TCL_ERROR;
	}
    }
233
234
235
236
237
238
239
240

241
242
243
244
245
246







247
248
249
250
251
252
253
287
288
289
290
291
292
293

294
295
296
297
298
299

300
301
302
303
304
305
306
307
308
309
310
311
312
313







-
+





-
+
+
+
+
+
+
+







static int
StringMatchSVG(
    Tcl_Obj *dataObj,
    Tcl_Obj *formatObj,
    int *widthPtr, int *heightPtr,
    Tcl_Interp *interp)
{
    TkSizeT length;
    TkSizeT length, testLength;
    const char *data;
    RastOpts ropts;
    NSVGimage *nsvgImage;

    CleanCache(interp);
    data = TkGetStringFromObj(dataObj, &length);
    data = Tcl_GetStringFromObj(dataObj, &length);
    /* should have a '<svg' and a '>' in the first 4k */
    testLength = (length > 4096) ? 4096 : length;
    if ((memchr(data, '>', testLength) == NULL) ||
	(MemMem(data, testLength, "<svg", 4) == NULL)) {
	return 0;
    }
    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;
        }
289
290
291
292
293
294
295
296

297
298
299
300
301
302
303
349
350
351
352
353
354
355

356
357
358
359
360
361
362
363







-
+







{
    TkSizeT length;
    const char *data;
    RastOpts ropts;
    NSVGimage *nsvgImage = GetCachedSVG(interp, dataObj, formatObj, &ropts);

    if (nsvgImage == NULL) {
        data = TkGetStringFromObj(dataObj, &length);
        data = Tcl_GetStringFromObj(dataObj, &length);
	nsvgImage = ParseSVGWithOptions(interp, data, length, formatObj,
			    &ropts);
    }
    if (nsvgImage == NULL) {
	return TCL_ERROR;
    }
    return RasterizeSVG(interp, imageHandle, nsvgImage, destX, destY,
332
333
334
335
336
337
338
339

340
341
342
343
344
345
346
392
393
394
395
396
397
398

399
400
401
402
403
404
405
406







-
+







    double dpi = 96.0;
    char *inputCopy = NULL;
    NSVGimage *nsvgImage;
    int parameterScaleSeen = 0;
    static const char *const fmtOptions[] = {
        "-dpi", "-scale", "-scaletoheight", "-scaletowidth", NULL
    };
    enum fmtOptions {
    enum fmtOptionsEnum {
	OPT_DPI, OPT_SCALE, OPT_SCALE_TO_HEIGHT, OPT_SCALE_TO_WIDTH
    };

    /*
     * The parser destroys the original input string,
     * therefore first duplicate.
     */
390
391
392
393
394
395
396
397

398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417

418
419
420
421
422
423
424
450
451
452
453
454
455
456

457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476

477
478
479
480
481
482
483
484







-
+



















-
+








	objc--;
	objv++;

	/*
	 * check that only one scale option is given
	 */
	switch ((enum fmtOptions) optIndex) {
	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 fmtOptions) optIndex) {
	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));
527
528
529
530
531
532
533









534

535
536
537
538
539
540
541
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602

603
604
605
606
607
608
609
610







+
+
+
+
+
+
+
+
+
-
+







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

    /* Tk Ticket [822330269b] Check potential int overflow in following ckalloc */
    unsigned long long wh = (unsigned long long)w * (unsigned long long)h;
    if ( wh > INT_MAX / 4) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("image size overflow", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "IMAGE_SIZE_OVERFLOW", NULL);
	goto cleanRAST;
    }

    imgData = (unsigned char *)attemptckalloc(w * h *4);
    imgData = (unsigned char *)attemptckalloc(wh * 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);
690
691
692
693
694
695
696
697

698
699
700
701
702
703
704
759
760
761
762
763
764
765

766
767
768
769
770
771
772
773







-
+







    TkSizeT length;
    const char *data;
    NSVGcache *cachePtr = GetCachePtr(interp);

    if (cachePtr != NULL) {
        cachePtr->dataOrChan = dataOrChan;
	if (formatObj != NULL) {
	    data = TkGetStringFromObj(formatObj, &length);
	    data = Tcl_GetStringFromObj(formatObj, &length);
	    Tcl_DStringAppend(&cachePtr->formatString, data, length);
	}
	cachePtr->nsvgImage = nsvgImage;
	cachePtr->ropts = *ropts;
	return 1;
    }
    return 0;
731
732
733
734
735
736
737
738

739
740
741
742
743
744
745
800
801
802
803
804
805
806

807
808
809
810
811
812
813
814







-
+







    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);
	    data = Tcl_GetStringFromObj(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;

Changes to generic/tkImgUtil.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





-
+







/*
 * tkImgUtil.c --
 *
 *	This file contains image related utility functions.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 * Copyright © 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "xbytes.h"

Changes to generic/tkInt.decls.

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






-
-
+
+







# tkInt.decls --
#
#	This file contains the declarations for all unsupported functions that
#	are exported by the Tk library. This file is used to generate the
#	tkIntDecls.h, tkIntPlatDecls.h, tkIntStub.c, and tkPlatStub.c files.
#
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright (c) 2007 Daniel A. Steffen <[email protected]>
# Copyright © 1998-1999 Scriptics Corporation.
# Copyright © 2007 Daniel A. Steffen <[email protected]>
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

library tk

##############################################################################
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645

646
647
648

649
650






651
652
653
654
655
656
657
631
632
633
634
635
636
637






638

639
640
641

642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657







-
-
-
-
-
-

-
+


-
+


+
+
+
+
+
+







}
declare 184 {
    void TkDrawAngledChars(Display *display,Drawable drawable, GC gc,
	    Tk_Font tkfont, const char *source, int numBytes, double x,
	    double y, double angle)
}

# Debugging / testing functions for photo images
declare 185 {
    int TkDebugPhotoStringMatchDef(Tcl_Interp *inter, Tcl_Obj *data,
            Tcl_Obj *formatString, int *widthPtr, int *heightPtr)
}

# Support for aqua's inability to draw outside [NSView drawRect:]
declare 186 aqua {
declare 185 macosx {
    void TkpRedrawWidget(Tk_Window tkwin)
}
declare 187 aqua {
declare 186 macosx {
    int TkpWillDrawWidget(Tk_Window tkwin)
}

# Debugging / testing functions for photo images
declare 187 {
    int TkDebugPhotoStringMatchDef(Tcl_Interp *inter, Tcl_Obj *data,
            Tcl_Obj *formatString, int *widthPtr, int *heightPtr)
}


##############################################################################

# Define the platform specific internal Tcl interface. These functions are
# only available on the designated platform.

914
915
916
917
918
919
920

921
922


923

924
925
926
927
928
929
930
914
915
916
917
918
919
920
921


922
923

924
925
926
927
928
929
930
931







+
-
-
+
+
-
+







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







+
-
-
+
+
-
+


















+
-
-
+
+
-
+







}
declare 24 aqua {
    void *TkMacOSXMakeStippleMap(Drawable d1, Drawable d2)
}
declare 25 aqua {
    void TkMacOSXMenuClick(void)
}
# The corresponding Unregister was not a stub, and this should be static.
declare 26 aqua {
    void TkMacOSXRegisterOffScreenWindow(Window window, void *portPtr)
#declare 26 aqua {
#    void TkMacOSXRegisterOffScreenWindow(Window window, void *portPtr)
}
#}
declare 27 aqua {
    int TkMacOSXResizable(TkWindow *winPtr)
}
declare 28 aqua {
    void TkMacOSXSetHelpMenuItemCount(void)
}
declare 29 aqua {
    void TkMacOSXSetScrollbarGrow(TkWindow *winPtr, int flag)
}
declare 30 aqua {
    void TkMacOSXSetUpClippingRgn(Drawable drawable)
}
declare 31 aqua {
    void TkMacOSXSetUpGraphicsPort(GC gc, void *destPort)
}
declare 32 aqua {
    void TkMacOSXUpdateClipRgn(TkWindow *winPtr)
}
# This was not implemented.  Perhaps meant to be OffScreen ?
declare 33 aqua {
    void TkMacOSXUnregisterMacWindow(void *portPtr)
#declare 33 aqua {
#    void TkMacOSXUnregisterMacWindow(void *portPtr)
}
#}
declare 34 aqua {
    int TkMacOSXUseMenuID(short macID)
}
declare 35 aqua {
    Region TkMacOSXVisableClipRgn(TkWindow *winPtr)
}
declare 36 aqua {
1023
1024
1025
1026
1027
1028
1029
1030

1031
1032
1033
1034
1035
1036
1037
1026
1027
1028
1029
1030
1031
1032

1033
1034
1035
1036
1037
1038
1039
1040







-
+







declare 46 aqua {
    int TkpIsWindowFloating(void *window)
}
declare 47 aqua {
    Tk_Window TkpGetCapture(void)
}
declare 49 aqua {
    Tk_Window TkGetTransientMaster(TkWindow *winPtr)
    Tk_Window TkMacOSXGetContainer(TkWindow *winPtr)
}
declare 50 aqua {
    int TkGenerateButtonEvent(int x, int y, Window window, unsigned int state)
}
declare 51 aqua {
    void TkGenWMDestroyEvent(Tk_Window tkwin)
}
1927
1928
1929
1930
1931
1932
1933




1934
1935
1936
1937
1938
1939
1940
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947







+
+
+
+







}
declare 104 macosx {
    Status XWithdrawWindow(Display *d, Window w, int i)
}
declare 105 macosx {
    XHostAddress *XListHosts(Display *d, int *i, Bool *b)
}
declare 106 macosx {
    int XSetClipRectangles(Display *display, GC gc, int clip_x_origin,
       int clip_y_origin, XRectangle rectangles[], int n, int ordering)
}
declare 107 macosx {
    int XFlush(Display *display)
}
declare 108 macosx {
    int XGrabServer(Display *display)
}
declare 109 macosx {

Changes to generic/tkInt.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








-
+







/*
 * 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
84
85
86
87
88
89
90










91
92
93
94
95
96
97
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107







+
+
+
+
+
+
+
+
+
+







#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 7)
# define Tcl_WCharToUtfDString ((char * (*)(const WCHAR *, int len, Tcl_DString *))Tcl_UniCharToUtfDString)
# define Tcl_UtfToWCharDString ((WCHAR * (*)(const char *, int len, Tcl_DString *))Tcl_UtfToUniCharDString)
# define Tcl_Char16ToUtfDString Tcl_UniCharToUtfDString
# define Tcl_UtfToChar16DString Tcl_UtfToUniCharDString
#endif

#if defined(__GNUC__) && (__GNUC__ > 2)
#   define TKFLEXARRAY 0
#else
#   define TKFLEXARRAY 1
#endif

#if !defined(Tcl_GetParent) && (TCL_MAJOR_VERSION < 9) && (TCL_MINOR_VERSION < 7)
#   define Tcl_GetParent Tcl_GetMaster
#endif

/*
 * Macros used to cast between pointers and integers (e.g. when storing an int
 * in ClientData), on 64-bit architectures they avoid gcc warning about "cast
 * to/from pointer from/to integer of different size".
 */

#if !defined(INT2PTR) && !defined(PTR2INT)
118
119
120
121
122
123
124






125
126
127
128
129
130
131
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147







+
+
+
+
+
+







#	define TCL_Z_MODIFIER	"I"
#   elif defined(__GNUC__) && !defined(_WIN32)
#	define TCL_Z_MODIFIER	"z"
#   else
#	define TCL_Z_MODIFIER	""
#   endif
#endif /* !TCL_Z_MODIFIER */
#undef TCL_LL_MODIFIER
#if defined(_WIN32) && (!defined(__USE_MINGW_ANSI_STDIO) || !__USE_MINGW_ANSI_STDIO)
#   define TCL_LL_MODIFIER	"I64"
#else
#   define TCL_LL_MODIFIER	"ll"
#endif

/*
 * Opaque type declarations:
 */

typedef struct TkColormap TkColormap;
typedef struct TkFontAttributes TkFontAttributes;
355
356
357
358
359
360
361
362
363
364



365
366
367

368
369
370
371
372
373
374
371
372
373
374
375
376
377



378
379
380
381
382

383
384
385
386
387
388
389
390







-
-
-
+
+
+


-
+







				 * initializing. */

    /*
     * Information used by tkGeometry.c only:
     */

    Tcl_HashTable maintainHashTable;
				/* Hash table that maps from a master's
				 * Tk_Window token to a list of slaves managed
				 * by that master. */
				/* Hash table that maps from a container's
				 * Tk_Window token to a list of windows managed
				 * by that container. */
    int geomInit;

#define TkGetGeomMaster(tkwin) (((TkWindow *)tkwin)->maintainerPtr != NULL ? \
#define TkGetContainer(tkwin) (((TkWindow *)tkwin)->maintainerPtr != NULL ? \
    ((TkWindow *)tkwin)->maintainerPtr : ((TkWindow *)tkwin)->parentPtr)

    /*
     * Information used by tkGet.c only:
     */

    Tcl_HashTable uidTable;	/* Stores all Tk_Uid used in a thread. */
438
439
440
441
442
443
444
445

446
447

448
449
450
451
452
453
454
454
455
456
457
458
459
460

461
462

463
464
465
466
467
468
469
470







-
+

-
+







				 * Packer structures. */

    /*
     * Information used by tkPlace.c only.
     */

    int placeInit;		/* 0 means tables below need initializing. */
    Tcl_HashTable masterTable;	/* Maps from Tk_Window toke to the Master
    Tcl_HashTable containerTable;	/* Maps from Tk_Window token to the Container
				 * structure for the window, if it exists. */
    Tcl_HashTable slaveTable;	/* Maps from Tk_Window toke to the Slave
    Tcl_HashTable contentTable;	/* Maps from Tk_Window token to the Content
				 * structure for the window, if it exists. */

    /*
     * Information used by tkSelect.c and tkClipboard.c only:
     */

    struct TkSelectionInfo *selectionInfoPtr;
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
588
589
590
591
592
593
594


595
596
597
598
599

600
601
602
603
604
605
606







-
-





-







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

/*
 * 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 {
675
676
677
678
679
680
681
682

683
684
685
686
687
688
689
688
689
690
691
692
693
694

695
696
697
698
699
700
701
702







-
+







				 * application has ever used. Used only by
				 * tkFocus.c. */

    struct ElArray *optionRootPtr;
				/* Top level of option hierarchy for this main
				 * window. NULL means uninitialized. Managed
				 * by tkOption.c. */
    Tcl_HashTable imageTable;	/* Maps from image names to Tk_ImageMaster
    Tcl_HashTable imageTable;	/* Maps from image names to Tk_ImageModel
				 * structures. Managed by tkImage.c. */
    int strictMotif;		/* This is linked to the tk_strictMotif global
				 * variable. */
    int alwaysShowSelection;	/* This is linked to the
				 * ::tk::AlwaysShowSelection variable. */
    struct TkMainInfo *nextPtr;	/* Next in list of all main windows managed by
				 * this process. */
722
723
724
725
726
727
728
729

730
731
732
733
734
735
736
735
736
737
738
739
740
741

742
743
744
745
746
747
748
749







-
+







    TkDisplay *dispPtr;		/* Tk's information about display for
				 * window. */
    int screenNum;		/* Index of screen for window, among all those
				 * for dispPtr. */
    Visual *visual;		/* Visual to use for window. If not default,
				 * MUST be set before X window is created. */
    int depth;			/* Number of bits/pixel. */
    Window window;		/* X's id for window. NULL means window hasn't
    Window window;		/* X's id for window. None means window hasn't
				 * actually been created yet, or it's been
				 * deleted. */
    struct TkWindow *childList;	/* First in list of child windows, or NULL if
				 * no children. List is in stacking order,
				 * lowest window first.*/
    struct TkWindow *lastChildPtr;
				/* Last in list of child windows (highest in
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
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







-
-
-
+
+
+

















-
+







    int minReqWidth;		/* Minimum requested width. */
    int minReqHeight;		/* Minimum requested height. */
#if defined(TK_USE_INPUT_METHODS) || (TCL_MAJOR_VERSION > 8)
    int ximGeneration;          /* Used to invalidate XIC */
#endif /* TK_USE_INPUT_METHODS */
    char *geomMgrName;          /* Records the name of the geometry manager. */
    struct TkWindow *maintainerPtr;
				/* The geometry master for this window. The
				 * value is NULL if the window has no master or
				 * if its master is its parent. */
				/* The geometry container for this window. The
				 * value is NULL if the window has no container or
				 * if its container is its parent. */
#if !defined(TK_USE_INPUT_METHODS) && (TCL_MAJOR_VERSION < 9)
    XIC inputContext;		/* XIM input context. */
    int ximGeneration;          /* Used to invalidate XIC */
#endif /* TK_USE_INPUT_METHODS */
} TkWindow;

/*
 * Real definition of some events. Note that these events come from outside
 * but have internally generated pieces added to them.
 */

typedef struct {
    XKeyEvent keyEvent;		/* The real event from X11. */
#ifdef _WIN32
    char trans_chars[XMaxTransChars];
                            /* translated characters */
    unsigned char nbytes;
#elif !defined(MAC_OSC_TK)
#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
				 * is non-NULL. */
1000
1001
1002
1003
1004
1005
1006





1007
1008
1009
1010
1011
1012
1013
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031







+
+
+
+
+







 * 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

1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1048
1049
1050
1051
1052
1053
1054


1055
1056
1057
1058
1059
1060
1061







-
-







 */

#define ALL_BUTTONS \
	(Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask \
		|Button6Mask|Button7Mask|Button8Mask|Button9Mask)


MODULE_SCOPE unsigned long TkGetButtonMask(unsigned int);

/*
 * Object types not declared in tkObj.c need to be mentioned here so they can
 * be properly registered with Tcl:
 */

MODULE_SCOPE const Tcl_ObjType tkBorderObjType;
MODULE_SCOPE const Tcl_ObjType tkBitmapObjType;
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276




1277
1278
1279
1280
1281
1282
1283
1279
1280
1281
1282
1283
1284
1285







1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296







-
-
-
-
-
-
-
+
+
+
+







			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_WinfoObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_WmObjCmd(ClientData clientData, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);

MODULE_SCOPE int	Tk_GetDoublePixelsFromObj(Tcl_Interp *interp,
			    Tk_Window tkwin, Tcl_Obj *objPtr,
			    double *doublePtr);
MODULE_SCOPE int	TkSetGeometryMaster(Tcl_Interp *interp,
			    Tk_Window tkwin, const char *master);
MODULE_SCOPE void	TkFreeGeometryMaster(Tk_Window tkwin,
			    const char *master);
MODULE_SCOPE int	TkSetGeometryContainer(Tcl_Interp *interp,
			    Tk_Window tkwin, const char *name);
MODULE_SCOPE void	TkFreeGeometryContainer(Tk_Window tkwin,
			    const char *name);

MODULE_SCOPE void	TkEventInit(void);
MODULE_SCOPE void	TkRegisterObjTypes(void);
MODULE_SCOPE int	TkDeadAppObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc, Tcl_Obj *const argv[]);
MODULE_SCOPE int	TkCanvasGetCoordObj(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tcl_Obj *obj,
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
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







-




+
+
+
+













-









-
-









+

-








+







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,
			    Tk_3DBorder border, int highlightWidth,
			    int borderWidth, int relief);
MODULE_SCOPE Tcl_Obj *	TkNewWindowObj(Tk_Window tkwin);
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 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);
1408
1409
1410
1411
1412
1413
1414
1415
1416


1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1422
1423
1424
1425
1426
1427
1428


1429
1430







1431
1432
1433
1434
1435
1436
1437







-
-
+
+
-
-
-
-
-
-
-







#   define TkUtfPrev Tcl_UtfPrev
#else
    MODULE_SCOPE size_t TkUtfToUniChar(const char *, int *);
    MODULE_SCOPE size_t TkUniCharToUtf(int, char *);
    MODULE_SCOPE const char *TkUtfPrev(const char *, const char *);
#endif

#if TCL_MAJOR_VERSION > 8
#define TkGetStringFromObj(objPtr, lenPtr) \
#if defined(_WIN32) && !defined(STATIC_BUILD) && TCL_MAJOR_VERSION < 9
#   define tcl_CreateFileHandler reserved9
	(((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
1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16








-
+







/*
 * 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
554
555
556
557
558
559
560

561







562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572








573
574
575
576
577
578
579







+

+
+
+
+
+
+
+



-
-
-
-
-
-
-
-







				int x, int y, int width, int height,
				double angle);
/* 184 */
EXTERN void		TkDrawAngledChars(Display *display,
				Drawable drawable, GC gc, Tk_Font tkfont,
				const char *source, int numBytes, double x,
				double y, double angle);
#ifdef MAC_OSX_TCL /* MACOSX */
/* 185 */
EXTERN void		TkpRedrawWidget(Tk_Window tkwin);
#endif /* MACOSX */
#ifdef MAC_OSX_TCL /* MACOSX */
/* 186 */
EXTERN int		TkpWillDrawWidget(Tk_Window tkwin);
#endif /* MACOSX */
/* 187 */
EXTERN int		TkDebugPhotoStringMatchDef(Tcl_Interp *inter,
				Tcl_Obj *data, Tcl_Obj *formatString,
				int *widthPtr, int *heightPtr);
#ifdef MAC_OSX_TK /* AQUA */
/* 186 */
EXTERN void		TkpRedrawWidget(Tk_Window tkwin);
#endif /* AQUA */
#ifdef MAC_OSX_TK /* AQUA */
/* 187 */
EXTERN int		TkpWillDrawWidget(Tk_Window tkwin);
#endif /* AQUA */

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







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

-
+



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







    const char * (*tkOrientPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr); /* 178 */
    int (*tkSmoothParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset); /* 179 */
    const char * (*tkSmoothPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr); /* 180 */
    void (*tkDrawAngledTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, double angle, int firstChar, int lastChar); /* 181 */
    void (*tkUnderlineAngledTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, double angle, int underline); /* 182 */
    int (*tkIntersectAngledTextLayout) (Tk_TextLayout layout, int x, int y, int width, int height, double angle); /* 183 */
    void (*tkDrawAngledChars) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *source, int numBytes, double x, double y, double angle); /* 184 */
    int (*tkDebugPhotoStringMatchDef) (Tcl_Interp *inter, Tcl_Obj *data, Tcl_Obj *formatString, int *widthPtr, int *heightPtr); /* 185 */
#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
    void (*reserved185)(void);
#endif /* UNIX */
#if defined(_WIN32) /* WIN */
    void (*reserved185)(void);
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
    void (*tkpRedrawWidget) (Tk_Window tkwin); /* 185 */
#endif /* MACOSX */
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
    void (*reserved186)(void);
#endif /* X11 */
#endif /* UNIX */
#if defined(_WIN32) /* WIN */
    void (*reserved186)(void);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
#ifdef MAC_OSX_TCL /* MACOSX */
    void (*reserved186)(void); /* Dummy entry for stubs table backwards compatibility */
    void (*tkpRedrawWidget) (Tk_Window tkwin); /* 186 */
#endif /* AQUA */
#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
    void (*reserved187)(void);
#endif /* X11 */
#if defined(_WIN32) /* WIN */
    void (*reserved187)(void);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    void (*reserved187)(void); /* Dummy entry for stubs table backwards compatibility */
    int (*tkpWillDrawWidget) (Tk_Window tkwin); /* 187 */
#endif /* AQUA */
    int (*tkpWillDrawWidget) (Tk_Window tkwin); /* 186 */
#endif /* MACOSX */
    int (*tkDebugPhotoStringMatchDef) (Tcl_Interp *inter, Tcl_Obj *data, Tcl_Obj *formatString, int *widthPtr, int *heightPtr); /* 187 */
} TkIntStubs;

extern const TkIntStubs *tkIntStubsPtr;

#ifdef __cplusplus
}
#endif
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
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







-
-
-
+

-
-
-
+
+
+

-
-
+
+
+
+

















+
+
+
+
+
+
+

	(tkIntStubsPtr->tkDrawAngledTextLayout) /* 181 */
#define TkUnderlineAngledTextLayout \
	(tkIntStubsPtr->tkUnderlineAngledTextLayout) /* 182 */
#define TkIntersectAngledTextLayout \
	(tkIntStubsPtr->tkIntersectAngledTextLayout) /* 183 */
#define TkDrawAngledChars \
	(tkIntStubsPtr->tkDrawAngledChars) /* 184 */
#define TkDebugPhotoStringMatchDef \
	(tkIntStubsPtr->tkDebugPhotoStringMatchDef) /* 185 */
#ifdef MAC_OSX_TK /* AQUA */
#ifdef MAC_OSX_TCL /* MACOSX */
#define TkpRedrawWidget \
	(tkIntStubsPtr->tkpRedrawWidget) /* 186 */
#endif /* AQUA */
#ifdef MAC_OSX_TK /* AQUA */
	(tkIntStubsPtr->tkpRedrawWidget) /* 185 */
#endif /* MACOSX */
#ifdef MAC_OSX_TCL /* MACOSX */
#define TkpWillDrawWidget \
	(tkIntStubsPtr->tkpWillDrawWidget) /* 187 */
#endif /* AQUA */
	(tkIntStubsPtr->tkpWillDrawWidget) /* 186 */
#endif /* MACOSX */
#define TkDebugPhotoStringMatchDef \
	(tkIntStubsPtr->tkDebugPhotoStringMatchDef) /* 187 */

#endif /* defined(USE_TK_STUBS) */

/* !END!: Do not edit above this line. */

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#undef TkpCmapStressed_
#undef TkpSync_
#undef TkUnixContainerId_
#undef TkUnixDoOneXEvent_
#undef TkUnixSetMenubar_
#undef TkWmCleanup_
#undef TkSendCleanup_
#undef TkpTestsendCmd_

#if !defined(MAC_OSX_TK)
#   undef TkpWillDrawWidget
#   undef TkpRedrawWidget
#   define TkpWillDrawWidget(w) 0
#   define TkpRedrawWidget(w)
#endif

#endif /* _TKINTDECLS */

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

173

174
175
176
177
178
179
180







-
+
-







EXTERN void		TkAboutDlg(void);
/* 8 */
EXTERN unsigned int	TkMacOSXButtonKeyState(void);
/* 9 */
EXTERN void		TkMacOSXClearMenubarActive(void);
/* 10 */
EXTERN int		TkMacOSXDispatchMenuEvent(int menuID, int index);
/* 11 */
/* Slot 11 is reserved */
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 */
195
196
197
198
199
200
201
202

203
204
205
206
207
208
209
210
211
212
213
214
215
216
217

218
219
220
221
222
223
224
225
194
195
196
197
198
199
200

201


202
203
204
205
206
207
208
209
210
211
212
213

214

215
216
217
218
219
220
221







-
+
-
-












-
+
-







				unsigned int searchChar);
/* 23 */
EXTERN void		TkMacOSXMakeRealWindowExist(TkWindow *winPtr);
/* 24 */
EXTERN void *		TkMacOSXMakeStippleMap(Drawable d1, Drawable d2);
/* 25 */
EXTERN void		TkMacOSXMenuClick(void);
/* 26 */
/* Slot 26 is reserved */
EXTERN void		TkMacOSXRegisterOffScreenWindow(Window window,
				void *portPtr);
/* 27 */
EXTERN int		TkMacOSXResizable(TkWindow *winPtr);
/* 28 */
EXTERN void		TkMacOSXSetHelpMenuItemCount(void);
/* 29 */
EXTERN void		TkMacOSXSetScrollbarGrow(TkWindow *winPtr, int flag);
/* 30 */
EXTERN void		TkMacOSXSetUpClippingRgn(Drawable drawable);
/* 31 */
EXTERN void		TkMacOSXSetUpGraphicsPort(GC gc, void *destPort);
/* 32 */
EXTERN void		TkMacOSXUpdateClipRgn(TkWindow *winPtr);
/* 33 */
/* Slot 33 is reserved */
EXTERN void		TkMacOSXUnregisterMacWindow(void *portPtr);
/* 34 */
EXTERN int		TkMacOSXUseMenuID(short macID);
/* 35 */
EXTERN Region		TkMacOSXVisableClipRgn(TkWindow *winPtr);
/* 36 */
EXTERN void		TkMacOSXWinBounds(TkWindow *winPtr, void *geometry);
/* 37 */
244
245
246
247
248
249
250
251

252
253
254
255
256
257
258
240
241
242
243
244
245
246

247
248
249
250
251
252
253
254







-
+







EXTERN void		TkMacOSXPreprocessMenu(void);
/* 46 */
EXTERN int		TkpIsWindowFloating(void *window);
/* 47 */
EXTERN Tk_Window	TkpGetCapture(void);
/* Slot 48 is reserved */
/* 49 */
EXTERN Tk_Window	TkGetTransientMaster(TkWindow *winPtr);
EXTERN Tk_Window	TkMacOSXGetContainer(TkWindow *winPtr);
/* 50 */
EXTERN int		TkGenerateButtonEvent(int x, int y, Window window,
				unsigned int state);
/* 51 */
EXTERN void		TkGenWMDestroyEvent(Tk_Window tkwin);
/* 52 */
EXTERN void		TkMacOSXSetDrawingEnabled(TkWindow *winPtr, int flag);
401
402
403
404
405
406
407
408

409
410
411
412
413
414
415
416
417
418
419
420
421
422
423

424
425
426
427
428
429
430

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

447
448
449
450
451
452
453
397
398
399
400
401
402
403

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

419
420
421
422
423
424
425

426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441

442
443
444
445
446
447
448
449







-
+














-
+






-
+















-
+







    void (*tkpSetCapture) (TkWindow *winPtr); /* 4 */
    void (*tkpSetCursor) (TkpCursor cursor); /* 5 */
    void (*tkpWmSetState) (TkWindow *winPtr, int state); /* 6 */
    void (*tkAboutDlg) (void); /* 7 */
    unsigned int (*tkMacOSXButtonKeyState) (void); /* 8 */
    void (*tkMacOSXClearMenubarActive) (void); /* 9 */
    int (*tkMacOSXDispatchMenuEvent) (int menuID, int index); /* 10 */
    void (*tkMacOSXInstallCursor) (int resizeOverride); /* 11 */
    void (*reserved11)(void);
    void (*tkMacOSXHandleTearoffMenu) (void); /* 12 */
    void (*reserved13)(void);
    int (*tkMacOSXDoHLEvent) (void *theEvent); /* 14 */
    void (*reserved15)(void);
    Window (*tkMacOSXGetXWindow) (void *macWinPtr); /* 16 */
    int (*tkMacOSXGrowToplevel) (void *whichWindow, XPoint start); /* 17 */
    void (*tkMacOSXHandleMenuSelect) (short theMenu, unsigned short theItem, int optionKeyPressed); /* 18 */
    void (*reserved19)(void);
    void (*reserved20)(void);
    void (*tkMacOSXInvalidateWindow) (MacDrawable *macWin, int flag); /* 21 */
    int (*tkMacOSXIsCharacterMissing) (Tk_Font tkfont, unsigned int searchChar); /* 22 */
    void (*tkMacOSXMakeRealWindowExist) (TkWindow *winPtr); /* 23 */
    void * (*tkMacOSXMakeStippleMap) (Drawable d1, Drawable d2); /* 24 */
    void (*tkMacOSXMenuClick) (void); /* 25 */
    void (*tkMacOSXRegisterOffScreenWindow) (Window window, void *portPtr); /* 26 */
    void (*reserved26)(void);
    int (*tkMacOSXResizable) (TkWindow *winPtr); /* 27 */
    void (*tkMacOSXSetHelpMenuItemCount) (void); /* 28 */
    void (*tkMacOSXSetScrollbarGrow) (TkWindow *winPtr, int flag); /* 29 */
    void (*tkMacOSXSetUpClippingRgn) (Drawable drawable); /* 30 */
    void (*tkMacOSXSetUpGraphicsPort) (GC gc, void *destPort); /* 31 */
    void (*tkMacOSXUpdateClipRgn) (TkWindow *winPtr); /* 32 */
    void (*tkMacOSXUnregisterMacWindow) (void *portPtr); /* 33 */
    void (*reserved33)(void);
    int (*tkMacOSXUseMenuID) (short macID); /* 34 */
    Region (*tkMacOSXVisableClipRgn) (TkWindow *winPtr); /* 35 */
    void (*tkMacOSXWinBounds) (TkWindow *winPtr, void *geometry); /* 36 */
    void (*tkMacOSXWindowOffset) (void *wRef, int *xOffset, int *yOffset); /* 37 */
    int (*tkSetMacColor) (unsigned long pixel, void *macColor); /* 38 */
    void (*tkSetWMName) (TkWindow *winPtr, Tk_Uid titleUid); /* 39 */
    void (*reserved40)(void);
    int (*tkMacOSXZoomToplevel) (void *whichWindow, short zoomPart); /* 41 */
    Tk_Window (*tk_TopCoordsToWindow) (Tk_Window tkwin, int rootX, int rootY, int *newX, int *newY); /* 42 */
    MacDrawable * (*tkMacOSXContainerId) (TkWindow *winPtr); /* 43 */
    MacDrawable * (*tkMacOSXGetHostToplevel) (TkWindow *winPtr); /* 44 */
    void (*tkMacOSXPreprocessMenu) (void); /* 45 */
    int (*tkpIsWindowFloating) (void *window); /* 46 */
    Tk_Window (*tkpGetCapture) (void); /* 47 */
    void (*reserved48)(void);
    Tk_Window (*tkGetTransientMaster) (TkWindow *winPtr); /* 49 */
    Tk_Window (*tkMacOSXGetContainer) (TkWindow *winPtr); /* 49 */
    int (*tkGenerateButtonEvent) (int x, int y, Window window, unsigned int state); /* 50 */
    void (*tkGenWMDestroyEvent) (Tk_Window tkwin); /* 51 */
    void (*tkMacOSXSetDrawingEnabled) (TkWindow *winPtr, int flag); /* 52 */
    unsigned long (*tkpGetMS) (void); /* 53 */
    void * (*tkMacOSXDrawable) (Drawable drawable); /* 54 */
    int (*tkpScanWindowId) (Tcl_Interp *interp, const char *string, Window *idPtr); /* 55 */
#endif /* AQUA */
627
628
629
630
631
632
633
634

635
636
637
638
639
640
641
642
623
624
625
626
627
628
629

630

631
632
633
634
635
636
637







-
+
-







	(tkIntPlatStubsPtr->tkAboutDlg) /* 7 */
#define TkMacOSXButtonKeyState \
	(tkIntPlatStubsPtr->tkMacOSXButtonKeyState) /* 8 */
#define TkMacOSXClearMenubarActive \
	(tkIntPlatStubsPtr->tkMacOSXClearMenubarActive) /* 9 */
#define TkMacOSXDispatchMenuEvent \
	(tkIntPlatStubsPtr->tkMacOSXDispatchMenuEvent) /* 10 */
#define TkMacOSXInstallCursor \
/* Slot 11 is reserved */
	(tkIntPlatStubsPtr->tkMacOSXInstallCursor) /* 11 */
#define TkMacOSXHandleTearoffMenu \
	(tkIntPlatStubsPtr->tkMacOSXHandleTearoffMenu) /* 12 */
/* Slot 13 is reserved */
#define TkMacOSXDoHLEvent \
	(tkIntPlatStubsPtr->tkMacOSXDoHLEvent) /* 14 */
/* Slot 15 is reserved */
#define TkMacOSXGetXWindow \
653
654
655
656
657
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
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







-
+
-












-
+
-







	(tkIntPlatStubsPtr->tkMacOSXIsCharacterMissing) /* 22 */
#define TkMacOSXMakeRealWindowExist \
	(tkIntPlatStubsPtr->tkMacOSXMakeRealWindowExist) /* 23 */
#define TkMacOSXMakeStippleMap \
	(tkIntPlatStubsPtr->tkMacOSXMakeStippleMap) /* 24 */
#define TkMacOSXMenuClick \
	(tkIntPlatStubsPtr->tkMacOSXMenuClick) /* 25 */
#define TkMacOSXRegisterOffScreenWindow \
/* Slot 26 is reserved */
	(tkIntPlatStubsPtr->tkMacOSXRegisterOffScreenWindow) /* 26 */
#define TkMacOSXResizable \
	(tkIntPlatStubsPtr->tkMacOSXResizable) /* 27 */
#define TkMacOSXSetHelpMenuItemCount \
	(tkIntPlatStubsPtr->tkMacOSXSetHelpMenuItemCount) /* 28 */
#define TkMacOSXSetScrollbarGrow \
	(tkIntPlatStubsPtr->tkMacOSXSetScrollbarGrow) /* 29 */
#define TkMacOSXSetUpClippingRgn \
	(tkIntPlatStubsPtr->tkMacOSXSetUpClippingRgn) /* 30 */
#define TkMacOSXSetUpGraphicsPort \
	(tkIntPlatStubsPtr->tkMacOSXSetUpGraphicsPort) /* 31 */
#define TkMacOSXUpdateClipRgn \
	(tkIntPlatStubsPtr->tkMacOSXUpdateClipRgn) /* 32 */
#define TkMacOSXUnregisterMacWindow \
/* Slot 33 is reserved */
	(tkIntPlatStubsPtr->tkMacOSXUnregisterMacWindow) /* 33 */
#define TkMacOSXUseMenuID \
	(tkIntPlatStubsPtr->tkMacOSXUseMenuID) /* 34 */
#define TkMacOSXVisableClipRgn \
	(tkIntPlatStubsPtr->tkMacOSXVisableClipRgn) /* 35 */
#define TkMacOSXWinBounds \
	(tkIntPlatStubsPtr->tkMacOSXWinBounds) /* 36 */
#define TkMacOSXWindowOffset \
697
698
699
700
701
702
703
704
705


706
707
708
709
710
711
712
690
691
692
693
694
695
696


697
698
699
700
701
702
703
704
705







-
-
+
+







#define TkMacOSXPreprocessMenu \
	(tkIntPlatStubsPtr->tkMacOSXPreprocessMenu) /* 45 */
#define TkpIsWindowFloating \
	(tkIntPlatStubsPtr->tkpIsWindowFloating) /* 46 */
#define TkpGetCapture \
	(tkIntPlatStubsPtr->tkpGetCapture) /* 47 */
/* Slot 48 is reserved */
#define TkGetTransientMaster \
	(tkIntPlatStubsPtr->tkGetTransientMaster) /* 49 */
#define TkMacOSXGetContainer \
	(tkIntPlatStubsPtr->tkMacOSXGetContainer) /* 49 */
#define TkGenerateButtonEvent \
	(tkIntPlatStubsPtr->tkGenerateButtonEvent) /* 50 */
#define TkGenWMDestroyEvent \
	(tkIntPlatStubsPtr->tkGenWMDestroyEvent) /* 51 */
#define TkMacOSXSetDrawingEnabled \
	(tkIntPlatStubsPtr->tkMacOSXSetDrawingEnabled) /* 52 */
#define TkpGetMS \
794
795
796
797
798
799
800

801
802
803
804
805
806
807
808
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802







+








#undef TkUnixContainerId_
#undef TkUnixDoOneXEvent_
#undef TkUnixSetMenubar_
#undef TkWmCleanup_
#undef TkSendCleanup_
#undef TkpTestsendCmd_
#undef TkGenerateActivateEvents_
#undef TkMacOSXSetUpClippingRgn

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#undef TkWinGetPlatformId
#define TkWinGetPlatformId() (2) /* VER_PLATFORM_WIN32_NT */

#endif /* _TKINTPLATDECLS */

Changes to generic/tkIntXlibDecls.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








-
+







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

/*
33
34
35
36
37
38
39




40
41
42
43
44
45
46
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50







+
+
+
+







#  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. */

761
762
763
764
765
766
767
768




769
770
771
772
773
774
775
765
766
767
768
769
770
771

772
773
774
775
776
777
778
779
780
781
782







-
+
+
+
+







				Window **wpp, int *ip);
/* 103 */
EXTERN Status		XIconifyWindow(Display *d, Window w, int i);
/* 104 */
EXTERN Status		XWithdrawWindow(Display *d, Window w, int i);
/* 105 */
EXTERN XHostAddress *	XListHosts(Display *d, int *i, Bool *b);
/* Slot 106 is reserved */
/* 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 */
1158
1159
1160
1161
1162
1163
1164
1165

1166
1167
1168
1169
1170
1171
1172
1165
1166
1167
1168
1169
1170
1171

1172
1173
1174
1175
1176
1177
1178
1179







-
+







    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 (*reserved106)(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 */
1744
1745
1746
1747
1748
1749
1750

1751

1752
1753
1754
1755
1756
1757
1758
1751
1752
1753
1754
1755
1756
1757
1758

1759
1760
1761
1762
1763
1764
1765
1766







+
-
+







	(tkIntXlibStubsPtr->xGetWMColormapWindows) /* 102 */
#define XIconifyWindow \
	(tkIntXlibStubsPtr->xIconifyWindow) /* 103 */
#define XWithdrawWindow \
	(tkIntXlibStubsPtr->xWithdrawWindow) /* 104 */
#define XListHosts \
	(tkIntXlibStubsPtr->xListHosts) /* 105 */
#define XSetClipRectangles \
/* Slot 106 is reserved */
	(tkIntXlibStubsPtr->xSetClipRectangles) /* 106 */
#define XFlush \
	(tkIntXlibStubsPtr->xFlush) /* 107 */
#define XGrabServer \
	(tkIntXlibStubsPtr->xGrabServer) /* 108 */
#define XUngrabServer \
	(tkIntXlibStubsPtr->xUngrabServer) /* 109 */
#define XFree \

Changes to generic/tkListbox.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







-
-
+
+







/*
 * tkListbox.c --
 *
 *	This module implements listbox widgets for the Tk toolkit. A listbox
 *	displays a collection of strings, one per line, and provides scrolling
 *	and selection.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "default.h"
575
576
577
578
579
580
581
582

583
584
585
586
587
588
589
575
576
577
578
579
580
581

582
583
584
585
586
587
588
589







-
+







    }

    if (ConfigureListbox(interp, listPtr, objc-2, objv+2) != TCL_OK) {
	Tk_DestroyWindow(listPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, TkNewWindowObj(listPtr->tkwin));
    Tcl_SetObjResult(interp, Tk_NewWindowObj(listPtr->tkwin));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ListboxWidgetObjCmd --
838
839
840
841
842
843
844
845

846
847
848
849
850
851
852
838
839
840
841
842
843
844

845
846
847
848
849
850
851
852







-
+







	    result = TCL_ERROR;
	    break;
	}
	result = GetListboxIndex(interp, listPtr, objv[2], 1, &index);
	if (result != TCL_OK) {
	    break;
	}
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index));
	Tcl_SetObjResult(interp, TkNewIndexObj(index));
	result = TCL_OK;
	break;

    case COMMAND_INSERT:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index ?element ...?");
	    result = TCL_ERROR;
902
903
904
905
906
907
908
909

910
911
912
913
914
915
916
902
903
904
905
906
907
908

909
910
911
912
913
914
915
916







-
+







    }

    case COMMAND_ITEMCONFIGURE: {
	ItemAttr *attrPtr;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "index ?-option? ?value? ?-option value ...?");
		    "index ?-option value ...?");
	    result = TCL_ERROR;
	    break;
	}

	result = GetListboxIndex(interp, listPtr, objv[2], 0, &index);
	if (result != TCL_OK) {
	    break;
1112
1113
1114
1115
1116
1117
1118
1119

1120
1121
1122
1123
1124
1125
1126
1112
1113
1114
1115
1116
1117
1118

1119
1120
1121
1122
1123
1124
1125
1126







-
+







	 */

	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)
2075
2076
2077
2078
2079
2080
2081
2082

2083
2084
2085
2086
2087
2088
2089
2075
2076
2077
2078
2079
2080
2081

2082
2083
2084
2085
2086
2087
2088
2089







-
+







	}

	/*
	 * 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;
2259
2260
2261
2262
2263
2264
2265
2266

2267
2268
2269
2270
2271
2272
2273
2259
2260
2261
2262
2263
2264
2265

2266
2267
2268
2269
2270
2271
2272
2273







-
+







	     */

	    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;
	    }
	}
    }
2337
2338
2339
2340
2341
2342
2343
2344

2345
2346
2347
2348
2349
2350
2351
2337
2338
2339
2340
2341
2342
2343

2344
2345
2346
2347
2348
2349
2350
2351







-
+







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

    /*
2496
2497
2498
2499
2500
2501
2502
2503

2504
2505
2506
2507
2508
2509
2510
2496
2497
2498
2499
2500
2501
2502

2503
2504
2505
2506
2507
2508
2509
2510







-
+







	 * 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;
	    }
	}
    }

2738
2739
2740
2741
2742
2743
2744
2745

2746
2747
2748
2749
2750
2751
2752
2738
2739
2740
2741
2742
2743
2744

2745
2746
2747
2748
2749
2750
2751
2752







-
+







{
    int result, index;
    TkSizeT idx;
    const char *stringRep;

    result = TkGetIntForIndex(indexObj, listPtr->nElements - 1, lastOK, &idx);
    if (result == TCL_OK) {
    	if (idx + 1 > (TkSizeT)listPtr->nElements + 1) {
    	if ((idx != TCL_INDEX_NONE) && (idx > (TkSizeT)listPtr->nElements)) {
    	    idx = listPtr->nElements;
    	}
    	*indexPtr = (int)idx;
    	return TCL_OK;
    }

    /*
3144
3145
3146
3147
3148
3149
3150
3151

3152
3153
3154
3155
3156
3157
3158
3144
3145
3146
3147
3148
3149
3150

3151
3152
3153
3154
3155
3156
3157
3158







-
+







	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) {
3225
3226
3227
3228
3229
3230
3231
3232

3233
3234
3235
3236
3237
3238
3239
3225
3226
3227
3228
3229
3230
3231

3232
3233
3234
3235
3236
3237
3238
3239







-
+







 *----------------------------------------------------------------------
 */

static void
GenerateListboxSelectEvent(
    Listbox *listPtr)		/* Information about widget. */
{
    TkSendVirtualEvent(listPtr->tkwin, "ListboxSelect", NULL);
    Tk_SendVirtualEvent(listPtr->tkwin, "ListboxSelect", NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * EventuallyRedrawRange --
 *

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

Changes to generic/tkMain.c.

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







-
+







     * For now, under Windows, we assume we are not running as a console mode
     * app, so we need to use the GUI console. In order to enable this, we
     * always claim to be running on a tty. This probably isn't the right way
     * to do it.
     */

#if !defined(STATIC_BUILD)
	if (tclStubsPtr->reserved9 && tclIntPlatStubsPtr->tclpIsAtty) {
	if (tclStubsPtr->tcl_CreateFileHandler && tclIntPlatStubsPtr->tclpIsAtty) {
	    /* We are running on Cygwin */
	    return tclIntPlatStubsPtr->tclpIsAtty(fd);
	}
#endif
    handle = GetStdHandle(STD_INPUT_HANDLE + fd);
	/*
	 * If it's a bad or closed handle, then it's been connected to a wish
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







-
+







	} else {
	    Tcl_Panic("%s", Tcl_GetString(Tcl_GetObjResult(interp)));
	}
    }

#if defined(_WIN32) && !defined(UNICODE) && !defined(STATIC_BUILD)

    if (tclStubsPtr->reserved9) {
    if (tclStubsPtr->tcl_CreateFileHandler) {
	/* 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)) {
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







-
+







    is.interp = interp;
    is.gotPartial = 0;
    Tcl_Preserve(interp);

#if defined(_WIN32)
#if !defined(STATIC_BUILD)
    /* If compiled for Win32 but running on Cygwin, don't use console */
    if (!tclStubsPtr->reserved9)
    if (!tclStubsPtr->tcl_CreateFileHandler)
#endif
    Tk_InitConsoleChannels(interp);
#endif

#ifdef MAC_OSX_TK
    if (Tcl_GetStartupScript(NULL) == NULL) {
	TkMacOSXDefaultStartupScript();
399
400
401
402
403
404
405
406

407
408
409
410

411
412
413
414

415



416



417
418

419
420
421
422
423
424
425
399
400
401
402
403
404
405

406
407
408
409

410
411
412
413

414
415
416
417
418

419
420
421
422

423
424
425
426
427
428
429
430







-
+



-
+



-
+

+
+
+
-
+
+
+

-
+







 *
 *----------------------------------------------------------------------
 */

static void
StdinProc(
    ClientData clientData,	/* The state of interactive cmd line */
    int mask)			/* Not used. */
    TCL_UNUSED(int))
{
    char *cmd;
    int code;
    size_t count;
    TkSizeT count;
    InteractiveState *isPtr = (InteractiveState *)clientData;
    Tcl_Channel chan = isPtr->input;
    Tcl_Interp *interp = isPtr->interp;
    (void)mask;
    Tcl_DString savedEncoding;

    Tcl_DStringInit(&savedEncoding);
    Tcl_GetChannelOption(NULL, chan, "-encoding", &savedEncoding);
    Tcl_SetChannelOption(NULL, chan, "-encoding", "utf-8");
    count = (size_t)Tcl_Gets(chan, &isPtr->line);
    count = Tcl_Gets(chan, &isPtr->line);
    Tcl_SetChannelOption(NULL, chan, "-encoding", Tcl_DStringValue(&savedEncoding));
    Tcl_DStringFree(&savedEncoding);

    if (count == (size_t)-1 && !isPtr->gotPartial) {
    if ((count == TCL_IO_FAILURE) && !isPtr->gotPartial) {
	if (isPtr->tty) {
	    Tcl_Exit(0);
	} else {
	    Tcl_DeleteChannelHandler(chan, StdinProc, isPtr);
	}
	return;
    }

Changes to generic/tkMenu.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








-
-
+
+







/*
 * tkMenu.c --
 *
 * This file contains most of the code for implementing menus in Tk. It takes
 * care of all of the generic (platform-independent) parts of menus, and is
 * supplemented by platform-specific files. The geometry calculation and
 * drawing code for menus is in the file tkMenuDraw.c
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1998 Sun Microsystems, Inc.
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1998 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

/*
 * Notes on implementation of menus:
35
36
37
38
39
40
41
42

43
44
45
46
47

48
49
50
51
52
53
54
35
36
37
38
39
40
41

42
43
44
45
46

47
48
49
50
51
52
53
54







-
+




-
+







 * menu bar must have a title that matches the label for the cascade menu.
 *
 * To handle all of the constraints, Tk menubars and tearoff menus are
 * implemented using menu clones. Menu clones are full menus in their own
 * right; they have a Tk window and pathname associated with them; they have a
 * TkMenu structure and array of entries. However, they are linked with the
 * original menu that they were cloned from. They reflect the attributes of the
 * original, or "master", menu. So if an item is added to a menu, and that
 * original, or "main", menu. So if an item is added to a menu, and that
 * menu has clones, then the item must be added to all of its clones also.
 * Menus are cloned when a menu is torn-off or when a menu is assigned as a
 * menubar using the "-menu" option of the toplevel's pathname configure
 * subcommand. When a clone is destroyed, only the clone is destroyed, but
 * when the master menu is destroyed, all clones are also destroyed. This
 * when the main menu is destroyed, all clones are also destroyed. This
 * allows the developer to just deal with one set of menus when creating and
 * destroying.
 *
 * Clones are rather tricky when a menu with cascade entries is cloned (such
 * as a menubar). Not only does the menu have to be cloned, but each cascade
 * entry's corresponding menu must also be cloned. This maintains the pathname
 * parent-child hierarchy necessary for menubars and toplevels to work. This
457
458
459
460
461
462
463
464

465
466
467
468
469
470
471
457
458
459
460
461
462
463

464
465
466
467
468
469
470
471







-
+







    menuPtr->display = Tk_Display(newWin);
    menuPtr->interp = interp;
    menuPtr->widgetCmd = Tcl_CreateObjCommand(interp,
	    Tk_PathName(menuPtr->tkwin), MenuWidgetObjCmd, menuPtr,
	    MenuCmdDeletedProc);
    menuPtr->active = TCL_INDEX_NONE;
    menuPtr->cursorPtr = NULL;
    menuPtr->masterMenuPtr = menuPtr;
    menuPtr->mainMenuPtr = menuPtr;
    menuPtr->menuType = UNKNOWN_TYPE;
    TkMenuInitializeDrawingFields(menuPtr);

    Tk_SetClass(menuPtr->tkwin, "Menu");
    Tk_SetClassProcs(menuPtr->tkwin, &menuClass, menuPtr);
    Tk_CreateEventHandler(newWin,
	    ExposureMask|StructureNotifyMask|ActivateMask,
514
515
516
517
518
519
520
521

522
523
524
525
526
527
528
529
530
531



532
533
534
535
536
537
538
514
515
516
517
518
519
520

521
522
523
524
525
526
527
528



529
530
531
532
533
534
535
536
537
538







-
+







-
-
-
+
+
+







	TkMenuEntry *nextCascadePtr;
	Tcl_Obj *newMenuName, *newObjv[2];

	while (cascadeListPtr != NULL) {
	    nextCascadePtr = cascadeListPtr->nextCascadePtr;

     	    /*
	     * If we have a new master menu, and an existing cloned menu
	     * If we have a new main menu, and an existing cloned menu
	     * points to this menu in a cascade entry, we have to clone the
	     * new menu and point the entry to the clone instead of the menu
	     * we are creating. Otherwise, ConfigureMenuEntry will hook up the
	     * platform-specific cascade linkages now that the menu we are
	     * creating exists.
     	     */

     	    if ((menuPtr->masterMenuPtr != menuPtr)
     	    	    || ((menuPtr->masterMenuPtr == menuPtr)
     	    	    && ((cascadeListPtr->menuPtr->masterMenuPtr
     	    if ((menuPtr->mainMenuPtr != menuPtr)
     	    	    || ((menuPtr->mainMenuPtr == menuPtr)
     	    	    && ((cascadeListPtr->menuPtr->mainMenuPtr
		    == cascadeListPtr->menuPtr)))) {
		newObjv[0] = Tcl_NewStringObj("-menu", -1);
		newObjv[1] = Tcl_NewStringObj(Tk_PathName(menuPtr->tkwin),-1);
		Tcl_IncrRefCount(newObjv[0]);
		Tcl_IncrRefCount(newObjv[1]);
     	    	ConfigureMenuEntry(cascadeListPtr, 2, newObjv);
		Tcl_DecrRefCount(newObjv[0]);
589
590
591
592
593
594
595
596

597
598
599
600
601
602
603
589
590
591
592
593
594
595

596
597
598
599
600
601
602
603







-
+







    	    listtkwin = topLevelListPtr->tkwin;
    	    TkSetWindowMenuBar(menuPtr->interp, listtkwin,
    	    	    Tk_PathName(menuPtr->tkwin), Tk_PathName(menuPtr->tkwin));
    	    topLevelListPtr = nextPtr;
    	}
    }

    Tcl_SetObjResult(interp, TkNewWindowObj(menuPtr->tkwin));
    Tcl_SetObjResult(interp, Tk_NewWindowObj(menuPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MenuWidgetObjCmd --
841
842
843
844
845
846
847
848
849


850
851
852
853
854
855
856
857
841
842
843
844
845
846
847


848
849

850
851
852
853
854
855
856







-
-
+
+
-







	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index == TCL_INDEX_NONE) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("none", -1));
	} else {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index));
	} else
	Tcl_SetObjResult(interp, TkNewIndexObj(index));
	}
	break;
    }
    case MENU_INSERT:
	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "index type ?-option value ...?");
	    goto error;
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
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







-
-
+
+








-
-
+
+


-
+

















-
+


-
-
-
+
+
+

-
+


















-
-
+
+









-
+







DestroyMenuInstance(
    TkMenu *menuPtr)		/* Info about menu widget. */
{
    int i;
    TkMenu *menuInstancePtr;
    TkMenuEntry *cascadePtr, *nextCascadePtr;
    Tcl_Obj *newObjv[2];
    TkMenu *parentMasterMenuPtr;
    TkMenuEntry *parentMasterEntryPtr;
    TkMenu *parentMainMenuPtr;
    TkMenuEntry *parentMainEntryPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * If the menu has any cascade menu entries pointing to it, the cascade
     * entries need to be told that the menu is going away. We need to clear
     * the menu ptr field in the menu reference at this point in the code so
     * that everything else can forget about this menu properly. We also need
     * to reset -menu field of all entries that are not master menus back to
     * this entry name if this is a master menu pointed to by another master
     * to reset -menu field of all entries that are not main menus back to
     * this entry name if this is a main menu pointed to by another main
     * menu. If there is a clone menu that points to this menu, then this menu
     * is itself a clone, so when this menu goes away, the -menu field of the
     * pointing entry must be set back to this menu's master menu name so that
     * pointing entry must be set back to this menu's main menu name so that
     * later if another menu is created the cascade hierarchy can be
     * maintained.
     */

    TkpDestroyMenu(menuPtr);
    if (menuPtr->menuRefPtr == NULL) {
	return;
    }
    cascadePtr = menuPtr->menuRefPtr->parentEntryPtr;
    menuPtr->menuRefPtr->menuPtr = NULL;
    if (TkFreeMenuReferences(menuPtr->menuRefPtr)) {
	menuPtr->menuRefPtr = NULL;
    }

    for (; cascadePtr != NULL; cascadePtr = nextCascadePtr) {
    	nextCascadePtr = cascadePtr->nextCascadePtr;

    	if (menuPtr->masterMenuPtr != menuPtr) {
    	if (menuPtr->mainMenuPtr != menuPtr) {
	    Tcl_Obj *menuNamePtr = Tcl_NewStringObj("-menu", -1);

	    parentMasterMenuPtr = cascadePtr->menuPtr->masterMenuPtr;
	    parentMasterEntryPtr =
		    parentMasterMenuPtr->entries[cascadePtr->index];
	    parentMainMenuPtr = cascadePtr->menuPtr->mainMenuPtr;
	    parentMainEntryPtr =
		    parentMainMenuPtr->entries[cascadePtr->index];
	    newObjv[0] = menuNamePtr;
	    newObjv[1] = parentMasterEntryPtr->namePtr;
	    newObjv[1] = parentMainEntryPtr->namePtr;

	    /*
	     * It is possible that the menu info is out of sync, and these
	     * things point to NULL, so verify existence [Bug: 3402]
	     */

	    if (newObjv[0] && newObjv[1]) {
		Tcl_IncrRefCount(newObjv[0]);
		Tcl_IncrRefCount(newObjv[1]);
		ConfigureMenuEntry(cascadePtr, 2, newObjv);
		Tcl_DecrRefCount(newObjv[0]);
		Tcl_DecrRefCount(newObjv[1]);
	    }
    	} else {
    	    ConfigureMenuEntry(cascadePtr, 0, NULL);
    	}
    }

    if (menuPtr->masterMenuPtr != menuPtr) {
	for (menuInstancePtr = menuPtr->masterMenuPtr;
    if (menuPtr->mainMenuPtr != menuPtr) {
	for (menuInstancePtr = menuPtr->mainMenuPtr;
		menuInstancePtr != NULL;
		menuInstancePtr = menuInstancePtr->nextInstancePtr) {
	    if (menuInstancePtr->nextInstancePtr == menuPtr) {
		menuInstancePtr->nextInstancePtr =
			menuInstancePtr->nextInstancePtr->nextInstancePtr;
		break;
	    }
	}
    } else if (menuPtr->nextInstancePtr != NULL) {
	Tcl_Panic("Attempting to delete master menu when there are still clones");
	Tcl_Panic("Attempting to delete main menu when there are still clones");
    }

    /*
     * Free up all the stuff that requires special handling, then let
     * Tk_FreeConfigOptions handle all the standard option-related stuff.
     */

1213
1214
1215
1216
1217
1218
1219
1220
1221


1222
1223
1224
1225
1226
1227
1228
1212
1213
1214
1215
1216
1217
1218


1219
1220
1221
1222
1223
1224
1225
1226
1227







-
-
+
+







/*
 *----------------------------------------------------------------------
 *
 * TkDestroyMenu --
 *
 *	This function is invoked by Tcl_EventuallyFree or Tcl_Release to clean
 *	up the internal structure of a menu at a safe time (when no-one is
 *	using it anymore). If called on a master instance, destroys all of the
 *	slave instances. If called on a non-master instance, just destroys
 *	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.
1260
1261
1262
1263
1264
1265
1266
1267

1268
1269
1270
1271
1272
1273
1274
1259
1260
1261
1262
1263
1264
1265

1266
1267
1268
1269
1270
1271
1272
1273







-
+







	topLevelListPtr = menuPtr->menuRefPtr->topLevelListPtr;
	while (topLevelListPtr != NULL) {
	    nextTopLevelPtr = topLevelListPtr->nextPtr;
	    TkpSetWindowMenuBar(topLevelListPtr->tkwin, NULL);
	    topLevelListPtr = nextTopLevelPtr;
	}
    }
    if (menuPtr->masterMenuPtr == menuPtr) {
    if (menuPtr->mainMenuPtr == menuPtr) {
	while (menuPtr->nextInstancePtr != NULL) {
	    menuInstancePtr = menuPtr->nextInstancePtr;
	    menuPtr->nextInstancePtr = menuInstancePtr->nextInstancePtr;
    	    if (menuInstancePtr->tkwin != NULL) {
		Tk_Window tkwin = menuInstancePtr->tkwin;

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







-
+



















-
+








    /*
     * Free up all the stuff that requires special handling, then let
     * Tk_FreeConfigOptions handle all the standard option-related stuff.
     */

    if (mePtr->type == CASCADE_ENTRY) {
	if (menuPtr->masterMenuPtr != menuPtr) {
	if (menuPtr->mainMenuPtr != menuPtr) {
	    TkMenu *destroyThis = NULL;
	    TkMenuReferences *menuRefPtr = mePtr->childMenuRefPtr;

	    /*
	     * The menu as a whole is a clone. We must delete the clone of the
	     * cascaded menu for the particular entry we are destroying.
	     */

	    if (menuRefPtr != NULL) {
		destroyThis = menuRefPtr->menuPtr;

		/*
		 * But only if it is a clone. What can happen is that we are
		 * in the middle of deleting a menu and this menu pointer has
		 * already been reset to point to the original menu. In that
		 * case we have nothing special to do.
		 */

		if ((destroyThis != NULL)
			&& (destroyThis->masterMenuPtr == destroyThis)) {
			&& (destroyThis->mainMenuPtr == destroyThis)) {
		    destroyThis = NULL;
		}
	    }
	    UnhookCascadeEntry(mePtr);
	    menuRefPtr = mePtr->childMenuRefPtr;
	    if (menuRefPtr != NULL) {
		if (menuRefPtr->menuPtr == destroyThis) {
1534
1535
1536
1537
1538
1539
1540
1541

1542
1543
1544
1545
1546
1547
1548

1549
1550
1551
1552
1553
1554
1555
1533
1534
1535
1536
1537
1538
1539

1540
1541
1542
1543
1544
1545
1546

1547
1548
1549
1550
1551
1552
1553
1554







-
+






-
+







{
    int i;
    TkMenu *menuListPtr, *cleanupPtr;
    int result;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (menuListPtr = menuPtr->masterMenuPtr; menuListPtr != NULL;
    for (menuListPtr = menuPtr->mainMenuPtr; menuListPtr != NULL;
	    menuListPtr = menuListPtr->nextInstancePtr) {
	menuListPtr->errorStructPtr = (Tk_SavedOptions *)ckalloc(sizeof(Tk_SavedOptions));
	result = Tk_SetOptions(interp, menuListPtr,
		tsdPtr->menuOptionTable, objc, objv,
		menuListPtr->tkwin, menuListPtr->errorStructPtr, NULL);
	if (result != TCL_OK) {
	    for (cleanupPtr = menuPtr->masterMenuPtr;
	    for (cleanupPtr = menuPtr->mainMenuPtr;
		    cleanupPtr != menuListPtr;
		    cleanupPtr = cleanupPtr->nextInstancePtr) {
		Tk_RestoreSavedOptions(cleanupPtr->errorStructPtr);
		ckfree(cleanupPtr->errorStructPtr);
		cleanupPtr->errorStructPtr = NULL;
	    }
	    if (menuListPtr->errorStructPtr != NULL) {
1575
1576
1577
1578
1579
1580
1581
1582

1583
1584
1585
1586
1587
1588
1589
1574
1575
1576
1577
1578
1579
1580

1581
1582
1583
1584
1585
1586
1587
1588







-
+







	     * Configure the new window to be either a pop-up menu or a
	     * tear-off menu. We don't do this for menubars since they are not
	     * toplevel windows. Also, since this gets called before CloneMenu
	     * has a chance to set the menuType field, we have to look at the
	     * menuTypeName field to tell that this is a menu bar.
	     */

	    if (menuListPtr->menuType == MASTER_MENU) {
	    if (menuListPtr->menuType == MAIN_MENU) {
		int typeFlag = TK_MAKE_MENU_POPUP;
		Tk_Window tkwin = menuPtr->tkwin;

		/*
		 * Work out if we are the child of a menubar or a popup.
		 */

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







-
+
















-







	 * an initial tear-off entry at the beginning of the menu.
	 */

	if (menuListPtr->tearoff) {
	    if ((menuListPtr->numEntries == 0)
		    || (menuListPtr->entries[0]->type != TEAROFF_ENTRY)) {
		if (MenuNewEntry(menuListPtr, 0, TEAROFF_ENTRY) == NULL) {
		    for (cleanupPtr = menuPtr->masterMenuPtr;
		    for (cleanupPtr = menuPtr->mainMenuPtr;
			    cleanupPtr != menuListPtr;
			    cleanupPtr = cleanupPtr->nextInstancePtr) {
			Tk_RestoreSavedOptions(cleanupPtr->errorStructPtr);
			ckfree(cleanupPtr->errorStructPtr);
			cleanupPtr->errorStructPtr = NULL;
		    }
		    if (menuListPtr->errorStructPtr != NULL) {
			Tk_RestoreSavedOptions(menuListPtr->errorStructPtr);
			ckfree(menuListPtr->errorStructPtr);
			menuListPtr->errorStructPtr = NULL;
		    }
		    return TCL_ERROR;
		}
	    }
	} else if ((menuListPtr->numEntries > 0)
		&& (menuListPtr->entries[0]->type == TEAROFF_ENTRY)) {
	    int i;

	    Tcl_EventuallyFree(menuListPtr->entries[0], (Tcl_FreeProc *) DestroyMenuEntry);

	    for (i = 0; i < (int)menuListPtr->numEntries - 1; i++) {
		menuListPtr->entries[i] = menuListPtr->entries[i + 1];
		menuListPtr->entries[i]->index = i;
	    }
1660
1661
1662
1663
1664
1665
1666
1667

1668
1669
1670
1671
1672
1673
1674
1658
1659
1660
1661
1662
1663
1664

1665
1666
1667
1668
1669
1670
1671
1672







-
+







	    mePtr = menuListPtr->entries[i];
	    ConfigureMenuEntry(mePtr, 0, NULL);
	}

	TkEventuallyRecomputeMenu(menuListPtr);
    }

    for (cleanupPtr = menuPtr->masterMenuPtr; cleanupPtr != NULL;
    for (cleanupPtr = menuPtr->mainMenuPtr; cleanupPtr != NULL;
	    cleanupPtr = cleanupPtr->nextInstancePtr) {
	Tk_FreeSavedOptions(cleanupPtr->errorStructPtr);
	ckfree(cleanupPtr->errorStructPtr);
	cleanupPtr->errorStructPtr = NULL;
    }

    return TCL_OK;
1708
1709
1710
1711
1712
1713
1714
1715

1716
1717
1718
1719
1720

1721
1722
1723
1724
1725
1726
1727
1706
1707
1708
1709
1710
1711
1712

1713
1714
1715
1716
1717

1718
1719
1720
1721
1722
1723
1724
1725







-
+




-
+







     * 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);
	(void)Tcl_GetStringFromObj(mePtr->labelPtr, &mePtr->labelLength);
    }
    if (mePtr->accelPtr == NULL) {
	mePtr->accelLength = 0;
    } else {
	(void)TkGetStringFromObj(mePtr->accelPtr, &mePtr->accelLength);
	(void)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.
     */
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1820
1821
1822
1823
1824
1825
1826

1827
1828
1829
1830
1831
1832
1833







-







	Tk_FreeImage(mePtr->selectImage);
    }
    mePtr->selectImage = image;

    if ((mePtr->type == CHECK_BUTTON_ENTRY)
	    || (mePtr->type == RADIO_BUTTON_ENTRY)) {
	Tcl_Obj *valuePtr;
	const char *name;

	if (mePtr->namePtr == NULL) {
	    if (mePtr->labelPtr == NULL) {
		mePtr->namePtr = NULL;
	    } else {
		mePtr->namePtr = Tcl_DuplicateObj(mePtr->labelPtr);
		Tcl_IncrRefCount(mePtr->namePtr);
1986
1987
1988
1989
1990
1991
1992
1993

1994
1995
1996
1997
1998
1999
2000

2001
2002
2003
2004
2005
2006
2007
1983
1984
1985
1986
1987
1988
1989

1990
1991
1992
1993
1994
1995
1996

1997
1998
1999
2000
2001
2002
2003
2004







-
+






-
+







    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 master
     * 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->masterMenuPtr->entries[index];
    mePtr = menuPtr->mainMenuPtr->entries[index];
    if (mePtr->type == CASCADE_ENTRY) {
	oldCascadePtr = mePtr->namePtr;
	if (oldCascadePtr != NULL) {
	    Tcl_IncrRefCount(oldCascadePtr);
	}
    }

2038
2039
2040
2041
2042
2043
2044
2045

2046
2047
2048
2049
2050
2051
2052
2035
2036
2037
2038
2039
2040
2041

2042
2043
2044
2045
2046
2047
2048
2049







-
+







	if (mePtr->namePtr != NULL) {
	    newCascadeName = Tcl_GetString(mePtr->namePtr);
	    cascadeMenuRefPtr = TkFindMenuReferences(menuPtr->interp,
		    newCascadeName);
	}
    }

    for (menuListPtr = menuPtr->masterMenuPtr->nextInstancePtr;
    for (menuListPtr = menuPtr->mainMenuPtr->nextInstancePtr;
    	    menuListPtr != NULL;
	    menuListPtr = menuListPtr->nextInstancePtr) {

    	mePtr = menuListPtr->entries[index];

	if (cascadeEntryChanged && (mePtr->namePtr != NULL)) {
	    oldCascadeMenuRefPtr = TkFindMenuReferencesObj(menuPtr->interp,
2125
2126
2127
2128
2129
2130
2131

2132

2133
2134
2135
2136
2137
2138
2139
2122
2123
2124
2125
2126
2127
2128
2129

2130
2131
2132
2133
2134
2135
2136
2137







+
-
+







				 * *after* last entry. */
    TkSizeT *indexPtr)		/* Where to store converted index. */
{
    int i;
    const char *string;

    if (TkGetIntForIndex(objPtr, menuPtr->numEntries - 1, lastOK, indexPtr) == TCL_OK) {
	/* TCL_INDEX_NONE is only accepted if it does not result from a negative number */
	if (*indexPtr != TCL_INDEX_NONE) {
	if (*indexPtr != TCL_INDEX_NONE || Tcl_GetString(objPtr)[0] != '-') {
	    if (*indexPtr >= menuPtr->numEntries) {
		*indexPtr = menuPtr->numEntries - ((lastOK) ? 0 : 1);
	    }
	    return TCL_OK;
	}
    }

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







-
+




















-
+










-
+







	    return TCL_ERROR;
	}
    } else {
	index = menuPtr->numEntries;
    }
    if (index == TCL_INDEX_NONE) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad index \"%s\"", Tcl_GetString(indexPtr)));
		"bad menu entry index \"%s\"", Tcl_GetString(indexPtr)));
	Tcl_SetErrorCode(interp, "TK", "MENU", "INDEX", NULL);
	return TCL_ERROR;
    }
    if (menuPtr->tearoff && (index == 0)) {
	index = 1;
    }

    /*
     * Figure out the type of the new entry.
     */

    if (Tcl_GetIndexFromObjStruct(interp, objv[0], menuEntryTypeStrings,
	    sizeof(char *), "menu entry type", 0, &type) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Now we have to add an entry for every instance related to this menu.
     */

    for (menuListPtr = menuPtr->masterMenuPtr; menuListPtr != NULL;
    for (menuListPtr = menuPtr->mainMenuPtr; menuListPtr != NULL;
    	    menuListPtr = menuListPtr->nextInstancePtr) {

    	mePtr = MenuNewEntry(menuListPtr, index, type);
    	if (mePtr == NULL) {
    	    return TCL_ERROR;
    	}
    	if (ConfigureMenuEntry(mePtr, objc - 1, objv + 1) != TCL_OK) {
	    TkMenu *errorMenuPtr;
	    TkSizeT i;

	    for (errorMenuPtr = menuPtr->masterMenuPtr;
	    for (errorMenuPtr = menuPtr->mainMenuPtr;
		    errorMenuPtr != NULL;
		    errorMenuPtr = errorMenuPtr->nextInstancePtr) {
    		Tcl_EventuallyFree(errorMenuPtr->entries[index],
    	    		(Tcl_FreeProc *) DestroyMenuEntry);
		for (i = index; i < errorMenuPtr->numEntries - 1; i++) {
		    errorMenuPtr->entries[i] = errorMenuPtr->entries[i + 1];
		    errorMenuPtr->entries[i]->index = i;
2413
2414
2415
2416
2417
2418
2419
2420

2421
2422
2423
2424
2425
2426
2427
2428
2429

2430
2431
2432
2433
2434
2435
2436
2411
2412
2413
2414
2415
2416
2417

2418
2419
2420
2421
2422
2423
2424
2425
2426

2427
2428
2429
2430
2431
2432
2433
2434







-
+








-
+







    	    return TCL_ERROR;
    	}

    	/*
	 * If a menu has cascades, then every instance of the menu has to have
	 * its own parallel cascade structure. So adding an entry to a menu
	 * with clones means that the menu that the entry points to has to be
	 * cloned for every clone the master menu has. This is special case #2
	 * cloned for every clone the main menu has. This is special case #2
	 * in the comment at the top of this file.
    	 */

    	if ((menuPtr != menuListPtr) && (type == CASCADE_ENTRY)) {
    	    if ((mePtr->namePtr != NULL)
		    && (mePtr->childMenuRefPtr != NULL)
    	    	    && (mePtr->childMenuRefPtr->menuPtr != NULL)) {
		TkMenu *cascadeMenuPtr =
			mePtr->childMenuRefPtr->menuPtr->masterMenuPtr;
			mePtr->childMenuRefPtr->menuPtr->mainMenuPtr;
		Tcl_Obj *newCascadePtr, *newObjv[2];
		Tcl_Obj *menuNamePtr = Tcl_NewStringObj("-menu", -1);
		Tcl_Obj *windowNamePtr =
			Tcl_NewStringObj(Tk_PathName(menuListPtr->tkwin), -1);
		Tcl_Obj *normalPtr = Tcl_NewStringObj("normal", -1);
		TkMenuReferences *menuRefPtr;

2696
2697
2698
2699
2700
2701
2702
2703

2704
2705
2706
2707
2708
2709
2710
2694
2695
2696
2697
2698
2699
2700

2701
2702
2703
2704
2705
2706
2707
2708







-
+







{
    int returnResult;
    int menuType, i;
    TkMenuReferences *menuRefPtr;
    Tcl_Obj *menuDupCommandArray[4];

    if (newMenuTypePtr == NULL) {
	menuType = MASTER_MENU;
	menuType = MAIN_MENU;
    } else {
	if (Tcl_GetIndexFromObjStruct(menuPtr->interp, newMenuTypePtr,
		menuTypeStrings, sizeof(char *), "menu type", 0, &menuType) != TCL_OK) {
	    return TCL_ERROR;
	}
    }

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







-
+








-
+

-
+

-
-
-
-
+
+
+
+



-
+








    if ((returnResult == TCL_OK) &&
	    ((menuRefPtr = TkFindMenuReferencesObj(menuPtr->interp,
	    newMenuNamePtr)) != NULL)
	    && (menuPtr->numEntries == menuRefPtr->menuPtr->numEntries)) {
	TkMenu *newMenuPtr = menuRefPtr->menuPtr;
	Tcl_Obj *newObjv[3];
	int i, numElements;
	int numElements;

	/*
	 * Now put this newly created menu into the parent menu's instance
	 * chain.
	 */

	if (menuPtr->nextInstancePtr == NULL) {
	    menuPtr->nextInstancePtr = newMenuPtr;
	    newMenuPtr->masterMenuPtr = menuPtr->masterMenuPtr;
	    newMenuPtr->mainMenuPtr = menuPtr->mainMenuPtr;
	} else {
	    TkMenu *masterMenuPtr;
	    TkMenu *mainMenuPtr;

	    masterMenuPtr = menuPtr->masterMenuPtr;
	    newMenuPtr->nextInstancePtr = masterMenuPtr->nextInstancePtr;
	    masterMenuPtr->nextInstancePtr = newMenuPtr;
	    newMenuPtr->masterMenuPtr = masterMenuPtr;
	    mainMenuPtr = menuPtr->mainMenuPtr;
	    newMenuPtr->nextInstancePtr = mainMenuPtr->nextInstancePtr;
	    mainMenuPtr->nextInstancePtr = newMenuPtr;
	    newMenuPtr->mainMenuPtr = mainMenuPtr;
	}

	/*
	 * Add the master menu's window to the bind tags for this window after
	 * Add the main menu's window to the bind tags for this window after
	 * this window's tag. This is so the user can bind to either this
	 * clone (which may not be easy to do) or the entire menu clone
	 * structure.
	 */

	newObjv[0] = Tcl_NewStringObj("bindtags", -1);
	newObjv[1] = Tcl_NewStringObj(Tk_PathName(newMenuPtr->tkwin), -1);
2777
2778
2779
2780
2781
2782
2783
2784

2785
2786
2787
2788
2789
2790
2791
2775
2776
2777
2778
2779
2780
2781

2782
2783
2784
2785
2786
2787
2788
2789







-
+







	    for (i = 0; i < numElements; i++) {
		Tcl_ListObjIndex(newMenuPtr->interp, bindingsPtr, i,
			&elementPtr);
		windowName = Tcl_GetString(elementPtr);
		if (strcmp(windowName, Tk_PathName(newMenuPtr->tkwin))
			== 0) {
		    Tcl_Obj *newElementPtr = Tcl_NewStringObj(
			    Tk_PathName(newMenuPtr->masterMenuPtr->tkwin), -1);
			    Tk_PathName(newMenuPtr->mainMenuPtr->tkwin), -1);

		    /*
		     * The newElementPtr will have its refCount incremented
		     * here, so we don't need to worry about it any more.
		     */

		    Tcl_ListObjReplace(menuPtr->interp, bindingsPtr,
3177
3178
3179
3180
3181
3182
3183
3184

3185
3186
3187
3188
3189
3190
3191
3175
3176
3177
3178
3179
3180
3181

3182
3183
3184
3185
3186
3187
3188
3189







-
+







	     */

	    if (menuRefPtr->menuPtr != NULL) {
		TkMenu *instancePtr;

		menuPtr = menuRefPtr->menuPtr;

		for (instancePtr = menuPtr->masterMenuPtr;
		for (instancePtr = menuPtr->mainMenuPtr;
			instancePtr != NULL;
			instancePtr = instancePtr->nextInstancePtr) {
		    if (instancePtr->menuType == MENUBAR
			    && instancePtr->parentTopLevelPtr == tkwin) {
			RecursivelyDeleteMenu(instancePtr);
			break;
		    }
3525
3526
3527
3528
3529
3530
3531
3532

3533
3534
3535
3536
3537
3538
3539
3523
3524
3525
3526
3527
3528
3529

3530
3531
3532
3533
3534
3535
3536
3537







-
+







				 * entries to delete. */
    int last)			/* The zero-based last entry. */
{
    TkMenu *menuListPtr;
    int numDeleted, i, j;

    numDeleted = last + 1 - first;
    for (menuListPtr = menuPtr->masterMenuPtr; menuListPtr != NULL;
    for (menuListPtr = menuPtr->mainMenuPtr; menuListPtr != NULL;
	    menuListPtr = menuListPtr->nextInstancePtr) {
	for (i = last; i >= first; i--) {
	    Tcl_EventuallyFree(menuListPtr->entries[i], (Tcl_FreeProc *) DestroyMenuEntry);
	}
	for (i = last + 1; i < (int)menuListPtr->numEntries; i++) {
	    j = i - numDeleted;
	    menuListPtr->entries[j] = menuListPtr->entries[i];

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







-
+







    int entryFlags;		/* Various flags. See below for
				 * definitions. */
    int index;			/* Need to know which index we are. This is
    				 * zero-based. This is the top-left entry of
    				 * the menu. */

    /*
     * Bookeeping for master menus and cascade menus.
     * Bookeeping for main menus and cascade menus.
     */

    struct TkMenuReferences *childMenuRefPtr;
    				/* A pointer to the hash table entry for the
    				 * child menu. Stored here when the menu entry
    				 * is configured so that a hash lookup is not
    				 * necessary later.*/
262
263
264
265
266
267
268
269

270
271
272
273
274
275
276
262
263
264
265
266
267
268

269
270
271
272
273
274
275
276







-
+







    Tcl_Interp *interp;		/* Interpreter associated with menu. */
    Tcl_Command widgetCmd;	/* Token for menu's widget command. */
    TkMenuEntry **entries;	/* Array of pointers to all the entries in the
				 * menu. NULL means no entries. */
    TkSizeT numEntries;		/* Number of elements in entries. */
    TkSizeT active;			/* Index of active entry. TCL_INDEX_NONE means
				 * nothing active. */
    int menuType;		/* MASTER_MENU, TEAROFF_MENU, or MENUBAR. See
    int menuType;		/* MAIN_MENU, TEAROFF_MENU, or MENUBAR. See
    				 * below for definitions. */
    Tcl_Obj *menuTypePtr;	/* Used to control whether created tkwin is a
				 * toplevel or not. "normal", "menubar", or
				 * "toplevel" */

    /*
     * Information used when displaying widget:
347
348
349
350
351
352
353
354

355
356
357

358
359
360
361
362
363
364
347
348
349
350
351
352
353

354
355
356

357
358
359
360
361
362
363
364







-
+


-
+







				 * definition. */
    TkMenuEntry *postedCascade;	/* Points to menu entry for cascaded submenu
				 * that is currently posted or NULL if no
				 * submenu posted. */
    struct TkMenu *nextInstancePtr;
    				/* The next instance of this menu in the
    				 * chain. */
    struct TkMenu *masterMenuPtr;
    struct TkMenu *mainMenuPtr;
    				/* A pointer to the original menu for this
    				 * clone chain. Points back to this structure
    				 * if this menu is a master menu. */
    				 * if this menu is a main menu. */
    void *reserved1; /* not used any more. */
    Tk_Window parentTopLevelPtr;/* If this menu is a menubar, this is the
    				 * toplevel that owns the menu. Only
    				 * applicable for menubar clones. */
    struct TkMenuReferences *menuRefPtr;
    				/* Each menu is hashed into a table with the
    				 * name of the menu's window as the key. The
430
431
432
433
434
435
436
437

438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455

456
457
458

459
460
461
462
463
464

465
466
467
468
469
470
471
430
431
432
433
434
435
436

437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454

455
456
457

458
459
460
461
462
463

464
465
466
467
468
469
470
471







-
+

















-
+


-
+





-
+







 * REDRAW_PENDING:		Non-zero means a DoWhenIdle handler has
 *				already been queued to redraw this window.
 * RESIZE_PENDING:		Non-zero means a call to ComputeMenuGeometry
 *				has already been scheduled.
 * MENU_DELETION_PENDING	Non-zero means that we are currently
 *				destroying this menu's internal structures.
 *				This is useful when we are in the middle of
 *				cleaning this master menu's chain of menus up
 *				cleaning this main menu's chain of menus up
 *				when TkDestroyMenu was called again on this
 *				menu (via a destroy binding or somesuch).
 * MENU_WIN_DESTRUCTION_PENDING Non-zero means we are in the middle of
 *				destroying this menu's Tk_Window.
 * MENU_PLATFORM_FLAG1...	Reserved for use by the platform-specific menu
 *				code.
 */

#define REDRAW_PENDING			1
#define RESIZE_PENDING			2
#define MENU_DELETION_PENDING		4
#define MENU_WIN_DESTRUCTION_PENDING	8
#define MENU_PLATFORM_FLAG1	(1 << 30)
#define MENU_PLATFORM_FLAG2	(1 << 29)
#define MENU_PLATFORM_FLAG3	(1 << 28)

/*
 * Each menu created by the user is a MASTER_MENU. When a menu is torn off, a
 * Each menu created by the user is a MAIN_MENU. When a menu is torn off, a
 * TEAROFF_MENU instance is created. When a menu is assigned to a toplevel as
 * a menu bar, a MENUBAR instance is created. All instances have the same
 * configuration information. If the master instance is deleted, all instances
 * 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 MASTER_MENU 		0
#define MAIN_MENU 		0
#define TEAROFF_MENU 		1
#define MENUBAR 		2

/*
 * Various geometry definitions:
 */

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

Changes to generic/tkMenubutton.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






-
-
+
+







-







/*
 * tkMenubutton.c --
 *
 *	This module implements button-like widgets that are used to invoke
 *	pull-down menus.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#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 = {
315
316
317
318
319
320
321
322

323
324
325
326
327
328
329
314
315
316
317
318
319
320

321
322
323
324
325
326
327
328







-
+







    }

    if (ConfigureMenuButton(interp, mbPtr, objc-2, objv+2) != TCL_OK) {
	Tk_DestroyWindow(mbPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, TkNewWindowObj(mbPtr->tkwin));
    Tcl_SetObjResult(interp, Tk_NewWindowObj(mbPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MenuButtonWidgetObjCmd --

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

Changes to generic/tkMessage.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







-
-
-
+
+
+







/*
 * 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 © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1998-2000 Ajuba Solutions.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "default.h"
274
275
276
277
278
279
280
281

282
283
284
285
286
287
288
274
275
276
277
278
279
280

281
282
283
284
285
286
287
288







-
+







    }

    if (ConfigureMessage(interp, msgPtr, objc-2, objv+2, 0) != TCL_OK) {
	Tk_DestroyWindow(msgPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, TkNewWindowObj(msgPtr->tkwin));
    Tcl_SetObjResult(interp, Tk_NewWindowObj(msgPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MessageWidgetObjCmd --

Changes to generic/tkObj.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





-
+







/*
 * tkObj.c --
 *
 *	This file contains functions that implement the common Tk object types
 *
 * Copyright (c) 1997 Sun Microsystems, Inc.
 * Copyright © 1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

95
96
97
98
99
100
101



102
103
104
105
106
107
108
109
110
111
112

113
114
115
116
117
118
119
120




121
122
123
124
125
126
127
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
132
133







+
+
+










-
+







-
+
+
+
+







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
#ifdef __cplusplus
extern "C" {
#endif
#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;
extern const 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 TclGetIntForIndex
# define Tcl_GetIntForIndex(interp, obj, max, ptr) TclGetIntForIndex(interp, obj, max, ptr)
#endif
#ifdef __cplusplus
}
#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.
961
962
963
964
965
966
967
968

969
970
971
972
973
974
975
976
977
978
979
980
967
968
969
970
971
972
973

974
975
976
977
978

979
980
981
982
983
984
985







-
+




-







 * 	TkGetWindowFromObj, which initializes the WindowRep cache.
 *
 *----------------------------------------------------------------------
 */

static int
SetWindowFromAny(
    Tcl_Interp *dummy,		/* Used for error reporting if not NULL. */
    TCL_UNUSED(Tcl_Interp *),
    Tcl_Obj *objPtr)	/* The object to convert. */
{
    const Tcl_ObjType *typePtr;
    WindowRep *winPtr;
    (void)dummy;

    /*
     * Free the old internalRep before setting the new one.
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
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
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







-
+














-
+







    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
    objPtr->typePtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkNewWindowObj --
 * Tk_NewWindowObj --
 *
 *	This function allocates a new Tcl_Obj that refers to a particular to a
 *	particular Tk window.
 *
 * Results:
 *	A standard Tcl object reference, with refcount 0.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkNewWindowObj(
Tk_NewWindowObj(
    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.

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







-
-
+
+







/*
 * tkOldConfig.c --
 *
 *	This file contains the Tk_ConfigureWidget function. THIS FILE IS HERE
 *	FOR BACKWARD COMPATIBILITY; THE NEW CONFIGURATION PACKAGE SHOULD BE
 *	USED FOR NEW PROJECTS.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

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







-
+






-
+



-
+



-
+





-
+







-
+







-
+







-
+







-
+







-
+



-
+







-
+


-
+


-
+


-
+


-
+



-
+



-
-
-
+







    const char *result;

    *freeProcPtr = NULL;
    ptr = (char *)widgRec + specPtr->offset;
    result = "";
    switch (specPtr->type) {
    case TK_CONFIG_BOOLEAN:
	if (*((int *) ptr) == 0) {
	if (*((int *)ptr) == 0) {
	    result = "0";
	} else {
	    result = "1";
	}
	break;
    case TK_CONFIG_INT:
	sprintf(buffer, "%d", *((int *) ptr));
	sprintf(buffer, "%d", *((int *)ptr));
	result = buffer;
	break;
    case TK_CONFIG_DOUBLE:
	Tcl_PrintDouble(interp, *((double *) ptr), buffer);
	Tcl_PrintDouble(interp, *((double *)ptr), buffer);
	result = buffer;
	break;
    case TK_CONFIG_STRING:
	result = (*(char **) ptr);
	result = (*(char **)ptr);
	if (result == NULL) {
	    result = "";
	}
	break;
    case TK_CONFIG_UID: {
	Tk_Uid uid = *((Tk_Uid *) ptr);
	Tk_Uid uid = *((Tk_Uid *)ptr);

	if (uid != NULL) {
	    result = uid;
	}
	break;
    }
    case TK_CONFIG_COLOR: {
	XColor *colorPtr = *((XColor **) ptr);
	XColor *colorPtr = *((XColor **)ptr);

	if (colorPtr != NULL) {
	    result = Tk_NameOfColor(colorPtr);
	}
	break;
    }
    case TK_CONFIG_FONT: {
	Tk_Font tkfont = *((Tk_Font *) ptr);
	Tk_Font tkfont = *((Tk_Font *)ptr);

	if (tkfont != NULL) {
	    result = Tk_NameOfFont(tkfont);
	}
	break;
    }
    case TK_CONFIG_BITMAP: {
	Pixmap pixmap = *((Pixmap *) ptr);
	Pixmap pixmap = *((Pixmap *)ptr);

	if (pixmap != None) {
	    result = Tk_NameOfBitmap(Tk_Display(tkwin), pixmap);
	}
	break;
    }
    case TK_CONFIG_BORDER: {
	Tk_3DBorder border = *((Tk_3DBorder *) ptr);
	Tk_3DBorder border = *((Tk_3DBorder *)ptr);

	if (border != NULL) {
	    result = Tk_NameOf3DBorder(border);
	}
	break;
    }
    case TK_CONFIG_RELIEF:
	result = Tk_NameOfRelief(*((int *) ptr));
	result = Tk_NameOfRelief(*((int *)ptr));
	break;
    case TK_CONFIG_CURSOR:
    case TK_CONFIG_ACTIVE_CURSOR: {
	Tk_Cursor cursor = *((Tk_Cursor *) ptr);
	Tk_Cursor cursor = *((Tk_Cursor *)ptr);

	if (cursor != NULL) {
	    result = Tk_NameOfCursor(Tk_Display(tkwin), cursor);
	}
	break;
    }
    case TK_CONFIG_JUSTIFY:
	result = Tk_NameOfJustify(*((Tk_Justify *) ptr));
	result = Tk_NameOfJustify(*((Tk_Justify *)ptr));
	break;
    case TK_CONFIG_ANCHOR:
	result = Tk_NameOfAnchor(*((Tk_Anchor *) ptr));
	result = Tk_NameOfAnchor(*((Tk_Anchor *)ptr));
	break;
    case TK_CONFIG_CAP_STYLE:
	result = Tk_NameOfCapStyle(*((int *) ptr));
	result = Tk_NameOfCapStyle(*((int *)ptr));
	break;
    case TK_CONFIG_JOIN_STYLE:
	result = Tk_NameOfJoinStyle(*((int *) ptr));
	result = Tk_NameOfJoinStyle(*((int *)ptr));
	break;
    case TK_CONFIG_PIXELS:
	sprintf(buffer, "%d", *((int *) ptr));
	sprintf(buffer, "%d", *((int *)ptr));
	result = buffer;
	break;
    case TK_CONFIG_MM:
	Tcl_PrintDouble(interp, *((double *) ptr), buffer);
	Tcl_PrintDouble(interp, *((double *)ptr), buffer);
	result = buffer;
	break;
    case TK_CONFIG_WINDOW: {
	Tk_Window tkwin;

	tkwin = *((Tk_Window *) ptr);
	tkwin = *((Tk_Window *)ptr);
	if (tkwin != NULL) {
	    result = Tk_PathName(tkwin);
	}
	break;
    }
    case TK_CONFIG_CUSTOM:
	result = specPtr->customPtr->printProc(specPtr->customPtr->clientData,
1104
1105
1106
1107
1108
1109
1110
1111

1112
1113
1114
1115
1116
1117
1118
1102
1103
1104
1105
1106
1107
1108

1109
1110
1111
1112
1113
1114
1115
1116







-
+







	for (staticSpecPtr=staticSpecs; staticSpecPtr->type!=TK_CONFIG_END;
		staticSpecPtr++) {
	    entrySpace += sizeof(Tk_ConfigSpec);
	}

	/*
	 * Now allocate our working copy's space and copy over the contents
	 * from the master copy.
	 * from the origin.
	 */

	cachedSpecs = (Tk_ConfigSpec *)ckalloc(entrySpace);
	memcpy(cachedSpecs, staticSpecs, entrySpace);
	Tcl_SetHashValue(entryPtr, cachedSpecs);

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







-
+




-







 *
 *--------------------------------------------------------------
 */

static void
DeleteSpecCacheTable(
    ClientData clientData,
    Tcl_Interp *dummy)
    TCL_UNUSED(Tcl_Interp *))
{
    Tcl_HashTable *tablePtr = (Tcl_HashTable *)clientData;
    Tcl_HashEntry *entryPtr;
    Tcl_HashSearch search;
    (void)dummy;

    for (entryPtr = Tcl_FirstHashEntry(tablePtr,&search); entryPtr != NULL;
	    entryPtr = Tcl_NextHashEntry(&search)) {
	/*
	 * Someone else deallocates the Tk_Uids themselves.
	 */

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
35
36
37
38
39

40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
1
2
3
4
5
6
7
8



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

29
30
31


32
33
34
35
36
37
38

39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65








-
-
-
+
+
+

















-
+


-
-
+
+





-
+







-
+










-
+







/*
 * 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 © 1993-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 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"

#if !defined(TK_NO_DEPRECATED) && (TCL_MAJOR_VERSION < 9)
/*
 * The following data structure represents the master for a test image:
 * The following data structure represents the model for a test image:
 */

typedef struct TImageMaster {
    Tk_ImageMaster master;      /* Tk's token for image master. */
typedef struct TImageModel {
    Tk_ImageModel model;        /* Tk's token for image model. */
    Tcl_Interp *interp;         /* Interpreter for application. */
    int width, height;          /* Dimensions of image. */
    char *imageName;            /* Name of image (malloc-ed). */
    char *varName;              /* Name of variable in which to log events for
                                 * image (malloc-ed). */
} TImageMaster;
} TImageModel;

/*
 * The following data structure represents a particular use of a particular
 * test image.
 */

typedef struct TImageInstance {
    TImageMaster *masterPtr;    /* Pointer to master for image. */
    TImageModel *modelPtr;    /* Pointer to model for image. */
    XColor *fg;                 /* Foreground color for drawing in image. */
    GC gc;                      /* Graphics context for drawing in image. */
} TImageInstance;

/*
 * The type record for test images:
 */

static int		ImageCreate(Tcl_Interp *interp,
			    char *name, int argc, char **argv,
			    Tk_ImageType *typePtr, Tk_ImageMaster master,
			    Tk_ImageType *typePtr, Tk_ImageModel model,
			    ClientData *clientDataPtr);
static ClientData	ImageGet(Tk_Window tkwin, ClientData clientData);
static void		ImageDisplay(ClientData clientData,
			    Display *display, Drawable drawable,
			    int imageX, int imageY, int width,
			    int height, int drawableX,
			    int drawableY);
142
143
144
145
146
147
148
149

150
151
152
153
154

155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175


176
177
178
179
180
181
182
183
184
185

186
187
188
189
190
191
192
142
143
144
145
146
147
148

149
150
151
152
153

154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173


174
175
176
177
178
179
180
181
182
183
184

185
186
187
188
189
190
191
192







-
+




-
+



















-
-
+
+









-
+







    Tcl_Interp *interp,		/* Interpreter for application containing
				 * image. */
    char *name,			/* Name to use for image. */
    int argc,			/* Number of arguments. */
    char **argv,		/* Argument strings for options (doesn't
				 * include image name or type). */
    Tk_ImageType *typePtr,	/* Pointer to our type record (not used). */
    Tk_ImageMaster master,	/* Token for image, to be used by us in later
    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. */
{
    TImageMaster *timPtr;
    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 = (TImageMaster *)ckalloc(sizeof(TImageMaster));
    timPtr->master = master;
    timPtr = (TImageModel *)ckalloc(sizeof(TImageModel));
    timPtr->model = model;
    timPtr->interp = interp;
    timPtr->width = 30;
    timPtr->height = 15;
    timPtr->imageName = (char *)ckalloc(strlen(name) + 1);
    strcpy(timPtr->imageName, name);
    timPtr->varName = (char *)ckalloc(strlen(varName) + 1);
    strcpy(timPtr->varName, varName);
    Tcl_CreateObjCommand(interp, name, ImageObjCmd, timPtr, NULL);
    *clientDataPtr = timPtr;
    Tk_ImageChanged(master, 0, 0, 30, 15, 30, 15);
    Tk_ImageChanged(model, 0, 0, 30, 15, 30, 15);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ImageObjCmd --
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
206
207
208
209
210
211
212

213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233

234
235
236
237
238
239
240
241







-
+




















-
+







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. */
{
    TImageMaster *timPtr = (TImageMaster *)clientData;
    TImageModel *timPtr = (TImageModel *)clientData;
    int x, y, width, height;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    if (strcmp(Tcl_GetString(objv[1]), "changed") == 0) {
	if (objc != 8) {
	    Tcl_WrongNumArgs(interp, 1, objv, "changed x y width height"
		    " imageWidth imageHeight");
	    return TCL_ERROR;
	}
	if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &width) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &height) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &timPtr->width) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[7], &timPtr->height) != TCL_OK)) {
	    return TCL_ERROR;
	}
	Tk_ImageChanged(timPtr->master, x, y, width, height, timPtr->width,
	Tk_ImageChanged(timPtr->model, x, y, width, height, timPtr->width,
		timPtr->height);
    } else {
	Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]),
		"\": must be changed", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
259
260
261
262
263
264
265
266

267
268

269
270
271
272
273
274
275
276
277
278

279
280
281
282
283
284
285
259
260
261
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 TImageMaster for image. */
    ClientData clientData)	/* Pointer to TImageModel for image. */
{
    TImageMaster *timPtr = (TImageMaster *)clientData;
    TImageModel *timPtr = (TImageModel *)clientData;
    TImageInstance *instPtr;
    char buffer[100];
    XGCValues gcValues;

    sprintf(buffer, "%s get", timPtr->imageName);
    Tcl_SetVar2(timPtr->interp, timPtr->varName, NULL, buffer,
	    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);

    instPtr = (TImageInstance *)ckalloc(sizeof(TImageInstance));
    instPtr->masterPtr = timPtr;
    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;
}

/*
312
313
314
315
316
317
318
319

320
321

322
323
324


325
326
327


328
329
330
331
332
333
334
312
313
314
315
316
317
318

319
320

321
322


323
324
325


326
327
328
329
330
331
332
333
334







-
+

-
+

-
-
+
+

-
-
+
+







				/* Coordinates in drawable corresponding to
				 * imageX and imageY. */
{
    TImageInstance *instPtr = (TImageInstance *)clientData;
    char buffer[200 + TCL_INTEGER_SPACE * 6];

    sprintf(buffer, "%s display %d %d %d %d %d %d",
	    instPtr->masterPtr->imageName, imageX, imageY, width, height,
	    instPtr->modelPtr->imageName, imageX, imageY, width, height,
	    drawableX, drawableY);
    Tcl_SetVar2(instPtr->masterPtr->interp, instPtr->masterPtr->varName, NULL,
    Tcl_SetVar2(instPtr->modelPtr->interp, instPtr->modelPtr->varName, NULL,
	    buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
    if (width > (instPtr->masterPtr->width - imageX)) {
	width = instPtr->masterPtr->width - imageX;
    if (width > (instPtr->modelPtr->width - imageX)) {
	width = instPtr->modelPtr->width - imageX;
    }
    if (height > (instPtr->masterPtr->height - imageY)) {
	height = instPtr->masterPtr->height - imageY;
    if (height > (instPtr->modelPtr->height - imageY)) {
	height = instPtr->modelPtr->height - imageY;
    }
    XDrawRectangle(display, drawable, instPtr->gc, drawableX, drawableY,
	    (unsigned) (width-1), (unsigned) (height-1));
    XDrawLine(display, drawable, instPtr->gc, drawableX, drawableY,
	    (int) (drawableX + width - 1), (int) (drawableY + height - 1));
    XDrawLine(display, drawable, instPtr->gc, drawableX,
	    (int) (drawableY + height - 1),
356
357
358
359
360
361
362
363
364


365
366
367
368
369
370
371
356
357
358
359
360
361
362


363
364
365
366
367
368
369
370
371







-
-
+
+







ImageFree(
    ClientData clientData,	/* Pointer to TImageInstance for instance. */
    Display *display)		/* Display where image was to be drawn. */
{
    TImageInstance *instPtr = (TImageInstance *)clientData;
    char buffer[200];

    sprintf(buffer, "%s free", instPtr->masterPtr->imageName);
    Tcl_SetVar2(instPtr->masterPtr->interp, instPtr->masterPtr->varName, NULL,
    sprintf(buffer, "%s free", instPtr->modelPtr->imageName);
    Tcl_SetVar2(instPtr->modelPtr->interp, instPtr->modelPtr->varName, NULL,
	    buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
    Tk_FreeColor(instPtr->fg);
    Tk_FreeGC(display, instPtr->gc);
    ckfree(instPtr);
}

/*
383
384
385
386
387
388
389
390

391
392
393
394

395
396
397
398
399
400
401
383
384
385
386
387
388
389

390
391
392
393

394
395
396
397
398
399
400
401







-
+



-
+







 *	Information about the image is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ImageDelete(
    ClientData clientData)	/* Pointer to TImageMaster for image. When
    ClientData clientData)	/* Pointer to TImageModel for image. When
				 * this function is called, no more instances
				 * exist. */
{
    TImageMaster *timPtr = (TImageMaster *)clientData;
    TImageModel *timPtr = (TImageModel *)clientData;
    char buffer[100];

    sprintf(buffer, "%s delete", timPtr->imageName);
    Tcl_SetVar2(timPtr->interp, timPtr->varName, NULL, buffer,
	    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);

    Tcl_DeleteCommand(timPtr->interp, timPtr->imageName);

Changes to generic/tkOption.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







-
-
+
+







/*
 * tkOption.c --
 *
 *	This module contains functions to manage the option database, which
 *	allows various strings to be associated with windows either by name or
 *	by class or both.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

517
518
519
520
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;
	size_t classNameLength;
	TkSizeT classNameLength;
	Element *nodePtr, *leafPtr;
	static const int searchOrder[] = {
	    EXACT_NODE_NAME, WILDCARD_NODE_NAME, EXACT_NODE_CLASS,
	    WILDCARD_NODE_CLASS, -1
	};
	const int *currentPtr;
	int currentStack, leafCount;

	/*
	 * Extract the masquerade class name from the name field.
	 */

	classNameLength	= (unsigned) (masqName - name);
	classNameLength	= masqName - name;
	masqClass = (char *)ckalloc(classNameLength + 1);
	strncpy(masqClass, name, classNameLength);
	masqClass[classNameLength] = '\0';

	winClassId = Tk_GetUid(masqClass);
	ckfree(masqClass);
	winNameId = ((TkWindow *) tkwin)->nameUid;
1081
1082
1083
1084
1085
1086
1087
1088

1089
1090
1091
1092
1093
1094
1095
1081
1082
1083
1084
1085
1086
1087

1088
1089
1090
1091
1092
1093
1094
1095







-
+







				 * 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;
    size_t 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
1112
1113
1114
1115
1116
1117
1118

1119
1120
1121
1122
1123
1124
1125
1126







-
+







	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 == (size_t)-1) {
    if (bufferSize == TCL_IO_FAILURE) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"error reading file \"%s\": %s",
		fileName, Tcl_PosixError(interp)));
	Tcl_Close(NULL, chan);
	return TCL_ERROR;
    }
    Tcl_Close(NULL, chan);
1416
1417
1418
1419
1420
1421
1422
1423

1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1416
1417
1418
1419
1420
1421
1422

1423
1424
1425
1426

1427
1428
1429
1430
1431
1432
1433







-
+



-







 *	Option-related data structures get freed.
 *
 *--------------------------------------------------------------
 */

static void
OptionThreadExitProc(
    ClientData dummy)	/* not used */
    TCL_UNUSED(void *))
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)dummy;

    if (tsdPtr->initialized) {
	int i;

	for (i = 0; i < NUM_STACKS; i++) {
	    ckfree(tsdPtr->stacks[i]);
	}

Changes to generic/tkPack.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
1
2
3
4
5
6


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

23
24
25
26
27
28
29
30
31

32
33
34

35
36
37



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

58
59
60
61
62
63

64
65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
80

81
82
83
84
85
86

87
88



89
90
91
92
93
94
95
96
97
98
99

100
101
102
103
104
105
106

107
108
109
110
111
112

113
114
115
116
117
118
119
120

121
122
123
124
125
126

127
128
129
130
131


132
133
134
135
136
137
138
139
140






-
-
+
+














-
+








-
+


-
+


-
-
-
+
+
+

















-
+





-
+








-
+







-
+





-
+

-
-
-
+
+
+








-
+






-
+





-
+







-
+





-
+




-
-
+
+







/*
 * tkPack.c --
 *
 *	This file contains code to implement the "packer" geometry manager for
 *	Tk.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

typedef enum {TOP, BOTTOM, LEFT, RIGHT} Side;
static const char *const sideNames[] = {
    "top", "bottom", "left", "right", NULL
};

/*
 * For each window that the packer cares about (either because the window is
 * managed by the packer or because the window has slaves that are managed by
 * managed by the packer or because the window has content that are managed by
 * the packer), there is a structure of the following type:
 */

typedef struct Packer {
    Tk_Window tkwin;		/* Tk token for window. NULL means that the
				 * window has been deleted, but the packet
				 * hasn't had a chance to clean up yet because
				 * the structure is still in use. */
    struct Packer *masterPtr;	/* Master window within which this window is
    struct Packer *containerPtr;	/* Container window within which this window is
				 * packed (NULL means this window isn't
				 * managed by the packer). */
    struct Packer *nextPtr;	/* Next window packed within same master. List
    struct Packer *nextPtr;	/* Next window packed within same container. List
				 * is priority-ordered: first on list gets
				 * packed first. */
    struct Packer *slavePtr;	/* First in list of slaves packed inside this
				 * window (NULL means no packed slaves). */
    Side side;			/* Side of master against which this window is
    struct Packer *contentPtr;	/* First in list of content packed inside this
				 * window (NULL means no packed content). */
    Side side;			/* Side of container against which this window is
				 * packed. */
    Tk_Anchor anchor;		/* If frame allocated for window is larger
				 * than window needs, this indicates how where
				 * to position window in frame. */
    int padX, padY;		/* Total additional pixels to leave around the
				 * window. Some is of this space is on each
				 * side. This is space *outside* the window:
				 * we'll allocate extra space in frame but
				 * won't enlarge window). */
    int padLeft, padTop;	/* The part of padX or padY to use on the left
				 * or top of the widget, respectively. By
				 * default, this is half of padX or padY. */
    int iPadX, iPadY;		/* Total extra pixels to allocate inside the
				 * window (half of this amount will appear on
				 * each side). */
    int doubleBw;		/* Twice the window's last known border width.
				 * If this changes, the window must be
				 * repacked within its master. */
				 * repacked within its container. */
    int *abortPtr;		/* If non-NULL, it means that there is a
				 * nested call to ArrangePacking already
				 * working on this window. *abortPtr may be
				 * set to 1 to abort that nested call. This
				 * happens, for example, if tkwin or any of
				 * its slaves is deleted. */
				 * its content is deleted. */
    int flags;			/* Miscellaneous flags; see below for
				 * definitions. */
} Packer;

/*
 * Flag values for Packer structures:
 *
 * REQUESTED_REPACK:		1 means a Tcl_DoWhenIdle request has already
 *				been made to repack all the slaves of this
 *				been made to repack all the content of this
 *				window.
 * FILLX:			1 means if frame allocated for window is wider
 *				than window needs, expand window to fill
 *				frame. 0 means don't make window any larger
 *				than needed.
 * FILLY:			Same as FILLX, except for height.
 * EXPAND:			1 means this window's frame will absorb any
 *				extra space in the master window.
 *				extra space in the container window.
 * OLD_STYLE:			1 means this window is being managed with the
 *				old-style packer algorithms (before Tk version
 *				3.3). The main difference is that padding and
 *				filling are done differently.
 * DONT_PROPAGATE:		1 means don't set this window's requested
 *				size. 0 means if this window is a master then
 *				size. 0 means if this window is a container then
 *				Tk will set its requested size to fit the
 *				needs of its slaves.
 * ALLOCED_MASTER               1 means that Pack has allocated itself as
 *                              geometry master for this window.
 *				needs of its content.
 * ALLOCED_CONTAINER	1 means that Pack has allocated itself as
 *				geometry container for this window.
 */

#define REQUESTED_REPACK	1
#define FILLX			2
#define FILLY			4
#define EXPAND			8
#define OLD_STYLE		16
#define DONT_PROPAGATE		32
#define ALLOCED_MASTER		64
#define ALLOCED_CONTAINER	64

/*
 * The following structure is the official type record for the packer:
 */

static void		PackReqProc(ClientData clientData, Tk_Window tkwin);
static void		PackLostSlaveProc(ClientData clientData,
static void		PackLostContentProc(ClientData clientData,
			    Tk_Window tkwin);

static const Tk_GeomMgr packerType = {
    "pack",			/* name */
    PackReqProc,		/* requestProc */
    PackLostSlaveProc,		/* lostSlaveProc */
    PackLostContentProc,		/* lostContentProc */
};

/*
 * Forward declarations for functions defined later in this file:
 */

static void		ArrangePacking(ClientData clientData);
static int		ConfigureSlaves(Tcl_Interp *interp, Tk_Window tkwin,
static int		ConfigureContent(Tcl_Interp *interp, Tk_Window tkwin,
			    int objc, Tcl_Obj *const objv[]);
static void		DestroyPacker(void *memPtr);
static Packer *		GetPacker(Tk_Window tkwin);
#ifndef TK_NO_DEPRECATED
static int		PackAfter(Tcl_Interp *interp, Packer *prevPtr,
			    Packer *masterPtr, int objc,Tcl_Obj *const objv[]);
			    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 *slavePtr, int cavityWidth);
static int		YExpansion(Packer *slavePtr, int cavityHeight);
static int		XExpansion(Packer *contentPtr, int cavityWidth);
static int		YExpansion(Packer *contentPtr, int cavityHeight);

/*
 *------------------------------------------------------------------------
 *
 * TkAppendPadAmount --
 *
 *	This function generates a text value that describes one of the -padx,
198
199
200
201
202
203
204
205



206
207
208
209
210

211
212
213
214
215
216
217

218
219
220
221
222
223
224
225

226
227
228
229
230
231
232
233
234
235

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

253
254
255
256
257
258

259
260
261

262
263
264
265
266
267
268
269


270
271
272
273
274
275

276
277
278

279
280
281
282
283
284
285
286

287
288
289
290
291
292
293


294
295
296
297
298
299
300
301
302
303
304
305
306

307
308
309
310
311
312
313
314
315
316

317
318
319


320
321
322
323

324
325
326
327
328
329
330
331






332
333
334


335
336
337
338
339
340
341


342
343
344
345
346
347
348

349
350
351
352


353
354
355
356
357
358
359
360
361

362
363

364
365
366


367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387




388
389

390
391
392
393
394
395


396
397
398
399
400
401
402

403
404
405

406
407
408

409
410
411
412
413
414
415
416

417
418
419
420


421
422
423

424
425

426
427
428
429


430
431
432
433


434
435
436
437



438
439
440
441
442



443
444

445
446
447
448
449
450




451
452
453
454
455
456
457

458
459
460
461
462
463



464
465

466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483

484
485

486
487

488
489
490
491
492
493
494
198
199
200
201
202
203
204

205
206
207
208
209
210
211

212
213
214
215
216
217
218

219
220
221
222
223
224
225
226

227
228

229
230
231
232
233
234


235
236

237
238
239
240
241
242
243
244
245
246
247
248
249
250

251
252
253
254
255
256

257
258
259

260
261
262
263
264
265
266


267
268
269
270
271
272
273

274
275
276

277
278
279
280
281
282
283
284

285
286
287
288
289
290


291
292
293
294
295
296
297
298
299
300
301
302
303
304

305
306
307
308
309
310
311
312
313
314

315
316


317
318
319
320
321

322
323
324






325
326
327
328
329
330
331


332
333
334
335
336
337
338


339
340
341
342
343
344
345
346

347
348
349


350
351
352
353
354
355
356
357
358
359

360
361

362
363


364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382




383
384
385
386
387

388
389
390
391
392


393
394
395
396
397
398
399
400

401
402
403

404
405
406

407
408
409
410
411
412
413
414

415
416
417


418
419
420
421

422
423

424
425
426


427
428
429
430


431
432
433



434
435
436
437
438



439
440
441
442

443
444
445
446



447
448
449
450
451
452
453
454
455
456

457
458
459
460



461
462
463
464

465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482

483
484

485
486

487
488
489
490
491
492
493
494







-
+
+
+




-
+






-
+







-
+

-






-
-
+

-














-
+





-
+


-
+






-
-
+
+





-
+


-
+







-
+





-
-
+
+












-
+









-
+

-
-
+
+



-
+


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

-
-
+
+





-
-
+
+






-
+


-
-
+
+








-
+

-
+

-
-
+
+

















-
-
-
-
+
+
+
+

-
+




-
-
+
+






-
+


-
+


-
+







-
+


-
-
+
+


-
+

-
+


-
-
+
+


-
-
+
+

-
-
-
+
+
+


-
-
-
+
+
+

-
+



-
-
-
+
+
+
+






-
+



-
-
-
+
+
+

-
+

















-
+

-
+

-
+







{
    Tk_Window tkwin = (Tk_Window)clientData;
    const char *argv2;
    static const char *const optionStrings[] = {
#ifndef TK_NO_DEPRECATED
	"after", "append", "before", "unpack",
#endif /* !TK_NO_DEPRECATED */
	"configure", "forget", "info", "propagate", "slaves", NULL };
	"configure", "content", "forget", "info", "propagate", "slaves", NULL };
    static const char *const optionStringsNoDep[] = {
	"configure", "content", "forget", "info", "propagate", NULL };
    enum options {
#ifndef TK_NO_DEPRECATED
	PACK_AFTER, PACK_APPEND, PACK_BEFORE, PACK_UNPACK,
#endif /* !TK_NO_DEPRECATED */
	PACK_CONFIGURE, PACK_FORGET, PACK_INFO, PACK_PROPAGATE, PACK_SLAVES };
	PACK_CONFIGURE, PACK_CONTENT, PACK_FORGET, PACK_INFO, PACK_PROPAGATE, PACK_SLAVES };
    int index;

    if (objc >= 2) {
	const char *string = Tcl_GetString(objv[1]);

	if (string[0] == '.') {
	    return ConfigureSlaves(interp, tkwin, objc-1, objv+1);
	    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(interp, objv[1], optionStrings,
    if (Tcl_GetIndexFromObjStruct(NULL, objv[1], optionStrings,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
#ifndef TK_NO_DEPRECATED
	/*
	 * Call it again without the deprecated ones to get a proper error
	 * message. This works well since there can't be any ambiguity between
	 * deprecated and new options.
	 */

	Tcl_ResetResult(interp);
	Tcl_GetIndexFromObjStruct(interp, objv[1], &optionStrings[4],
	Tcl_GetIndexFromObjStruct(interp, objv[1], optionStringsNoDep,
		sizeof(char *), "option", 0, &index);
#endif /* TK_NO_DEPRECATED */
	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->masterPtr == NULL) {
	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->masterPtr, objc-3, objv+3);
	return PackAfter(interp, prevPtr, prevPtr->containerPtr, objc-3, objv+3);
    }
    case PACK_APPEND: {
	Packer *masterPtr;
	Packer *containerPtr;
	Packer *prevPtr;
	Tk_Window tkwin2;

	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	masterPtr = GetPacker(tkwin2);
	prevPtr = masterPtr->slavePtr;
	containerPtr = GetPacker(tkwin2);
	prevPtr = containerPtr->contentPtr;
	if (prevPtr != NULL) {
	    while (prevPtr->nextPtr != NULL) {
		prevPtr = prevPtr->nextPtr;
	    }
	}
	return PackAfter(interp, prevPtr, masterPtr, objc-3, objv+3);
	return PackAfter(interp, prevPtr, containerPtr, objc-3, objv+3);
    }
    case PACK_BEFORE: {
	Packer *packPtr, *masterPtr;
	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->masterPtr == NULL) {
	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;
	}
	masterPtr = packPtr->masterPtr;
	prevPtr = masterPtr->slavePtr;
	containerPtr = packPtr->containerPtr;
	prevPtr = containerPtr->contentPtr;
	if (prevPtr == packPtr) {
	    prevPtr = NULL;
	} else {
	    for ( ; ; prevPtr = prevPtr->nextPtr) {
		if (prevPtr == NULL) {
		    Tcl_Panic("\"pack before\" couldn't find predecessor");
		}
		if (prevPtr->nextPtr == packPtr) {
		    break;
		}
	    }
	}
	return PackAfter(interp, prevPtr, masterPtr, objc-3, objv+3);
	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 ConfigureSlaves(interp, tkwin, objc-2, objv+2);
	return ConfigureContent(interp, tkwin, objc-2, objv+2);
    case PACK_FORGET: {
	Tk_Window slave;
	Packer *slavePtr;
	Tk_Window content;
	Packer *contentPtr;
	int i;

	for (i = 2; i < objc; i++) {
	    if (TkGetWindowFromObj(interp, tkwin, objv[i], &slave) != TCL_OK) {
	    if (TkGetWindowFromObj(interp, tkwin, objv[i], &content) != TCL_OK) {
		continue;
	    }
	    slavePtr = GetPacker(slave);
	    if ((slavePtr != NULL) && (slavePtr->masterPtr != NULL)) {
		Tk_ManageGeometry(slave, NULL, NULL);
		if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) {
		    Tk_UnmaintainGeometry(slavePtr->tkwin,
			    slavePtr->masterPtr->tkwin);
	    contentPtr = GetPacker(content);
	    if ((contentPtr != NULL) && (contentPtr->containerPtr != NULL)) {
		Tk_ManageGeometry(content, NULL, NULL);
		if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
		    Tk_UnmaintainGeometry(contentPtr->tkwin,
			    contentPtr->containerPtr->tkwin);
		}
		Unlink(slavePtr);
		Tk_UnmapWindow(slavePtr->tkwin);
		Unlink(contentPtr);
		Tk_UnmapWindow(contentPtr->tkwin);
	    }
	}
	break;
    }
    case PACK_INFO: {
	Packer *slavePtr;
	Tk_Window slave;
	Packer *contentPtr;
	Tk_Window content;
	Tcl_Obj *infoObj;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &slave) != TCL_OK) {
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &content) != TCL_OK) {
	    return TCL_ERROR;
	}
	slavePtr = GetPacker(slave);
	if (slavePtr->masterPtr == NULL) {
	contentPtr = GetPacker(content);
	if (contentPtr->containerPtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" isn't packed", argv2));
	    Tcl_SetErrorCode(interp, "TK", "PACK", "NOT_PACKED", NULL);
	    return TCL_ERROR;
	}

	infoObj = Tcl_NewObj();
	Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-in", -1),
		TkNewWindowObj(slavePtr->masterPtr->tkwin));
		Tk_NewWindowObj(contentPtr->containerPtr->tkwin));
	Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-anchor", -1),
		Tcl_NewStringObj(Tk_NameOfAnchor(slavePtr->anchor), -1));
		Tcl_NewStringObj(Tk_NameOfAnchor(contentPtr->anchor), -1));
	Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-expand", -1),
		Tcl_NewBooleanObj(slavePtr->flags & EXPAND));
	switch (slavePtr->flags & (FILLX|FILLY)) {
		Tcl_NewBooleanObj(contentPtr->flags & EXPAND));
	switch (contentPtr->flags & (FILLX|FILLY)) {
	case 0:
	    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-fill", -1),
		    Tcl_NewStringObj("none", -1));
	    break;
	case FILLX:
	    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-fill", -1),
		    Tcl_NewStringObj("x", -1));
	    break;
	case FILLY:
	    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-fill", -1),
		    Tcl_NewStringObj("y", -1));
	    break;
	case FILLX|FILLY:
	    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-fill", -1),
		    Tcl_NewStringObj("both", -1));
	    break;
	}
	TkAppendPadAmount(infoObj, "-ipadx", slavePtr->iPadX/2, slavePtr->iPadX);
	TkAppendPadAmount(infoObj, "-ipady", slavePtr->iPadY/2, slavePtr->iPadY);
	TkAppendPadAmount(infoObj, "-padx", slavePtr->padLeft,slavePtr->padX);
	TkAppendPadAmount(infoObj, "-pady", slavePtr->padTop, slavePtr->padY);
	TkAppendPadAmount(infoObj, "-ipadx", contentPtr->iPadX/2, contentPtr->iPadX);
	TkAppendPadAmount(infoObj, "-ipady", contentPtr->iPadY/2, contentPtr->iPadY);
	TkAppendPadAmount(infoObj, "-padx", contentPtr->padLeft,contentPtr->padX);
	TkAppendPadAmount(infoObj, "-pady", contentPtr->padTop, contentPtr->padY);
	Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-side", -1),
		Tcl_NewStringObj(sideNames[slavePtr->side], -1));
		Tcl_NewStringObj(sideNames[contentPtr->side], -1));
	Tcl_SetObjResult(interp, infoObj);
	break;
    }
    case PACK_PROPAGATE: {
	Tk_Window master;
	Packer *masterPtr;
	Tk_Window container;
	Packer *containerPtr;
	int propagate;

	if (objc > 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	    return TCL_ERROR;
	}
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &master) != TCL_OK) {
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	    return TCL_ERROR;
	}
	masterPtr = GetPacker(master);
	containerPtr = GetPacker(container);
	if (objc == 3) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewBooleanObj(!(masterPtr->flags & DONT_PROPAGATE)));
		    Tcl_NewBooleanObj(!(containerPtr->flags & DONT_PROPAGATE)));
	    return TCL_OK;
	}
	if (Tcl_GetBooleanFromObj(interp, objv[3], &propagate) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (propagate) {
	    /*
	     * If we have slaves, we need to register as geometry master.
	     * If we have content windows, we need to register as geometry container.
	     */

	    if (masterPtr->slavePtr != NULL) {
		if (TkSetGeometryMaster(interp, master, "pack") != TCL_OK) {
	    if (containerPtr->contentPtr != NULL) {
		if (TkSetGeometryContainer(interp, container, "pack") != TCL_OK) {
		    return TCL_ERROR;
		}
		masterPtr->flags |= ALLOCED_MASTER;
		containerPtr->flags |= ALLOCED_CONTAINER;
	    }
	    masterPtr->flags &= ~DONT_PROPAGATE;
	    containerPtr->flags &= ~DONT_PROPAGATE;

	    /*
	     * Repack the master to allow new geometry information to
	     * propagate upwards to the master's master.
	     * Repack the container to allow new geometry information to
	     * propagate upwards to the container's container.
	     */

	    if (masterPtr->abortPtr != NULL) {
		*masterPtr->abortPtr = 1;
	    if (containerPtr->abortPtr != NULL) {
		*containerPtr->abortPtr = 1;
	    }
	    if (!(masterPtr->flags & REQUESTED_REPACK)) {
		masterPtr->flags |= REQUESTED_REPACK;
		Tcl_DoWhenIdle(ArrangePacking, masterPtr);
	    if (!(containerPtr->flags & REQUESTED_REPACK)) {
		containerPtr->flags |= REQUESTED_REPACK;
		Tcl_DoWhenIdle(ArrangePacking, containerPtr);
	    }
	} else {
	    if (masterPtr->flags & ALLOCED_MASTER) {
		TkFreeGeometryMaster(master, "pack");
		masterPtr->flags &= ~ALLOCED_MASTER;
	    if (containerPtr->flags & ALLOCED_CONTAINER) {
		TkFreeGeometryContainer(container, "pack");
		containerPtr->flags &= ~ALLOCED_CONTAINER;
	    }
	    masterPtr->flags |= DONT_PROPAGATE;
	    containerPtr->flags |= DONT_PROPAGATE;
	}
	break;
    }
    case PACK_SLAVES: {
	Tk_Window master;
	Packer *masterPtr, *slavePtr;
    case PACK_SLAVES:
    case PACK_CONTENT: {
	Tk_Window container;
	Packer *containerPtr, *contentPtr;
	Tcl_Obj *resultObj;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &master) != TCL_OK) {
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	    return TCL_ERROR;
	}
	resultObj = Tcl_NewObj();
	masterPtr = GetPacker(master);
	for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
		slavePtr = slavePtr->nextPtr) {
	containerPtr = GetPacker(container);
	for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
		contentPtr = contentPtr->nextPtr) {
	    Tcl_ListObjAppendElement(NULL, resultObj,
		    TkNewWindowObj(slavePtr->tkwin));
		    Tk_NewWindowObj(contentPtr->tkwin));
	}
	Tcl_SetObjResult(interp, resultObj);
	break;
    }
#ifndef TK_NO_DEPRECATED
    case PACK_UNPACK: {
	Tk_Window tkwin2;
	Packer *packPtr;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	packPtr = GetPacker(tkwin2);
	if ((packPtr != NULL) && (packPtr->masterPtr != NULL)) {
	if ((packPtr != NULL) && (packPtr->containerPtr != NULL)) {
	    Tk_ManageGeometry(tkwin2, NULL, NULL);
	    if (packPtr->masterPtr->tkwin != Tk_Parent(packPtr->tkwin)) {
	    if (packPtr->containerPtr->tkwin != Tk_Parent(packPtr->tkwin)) {
		Tk_UnmaintainGeometry(packPtr->tkwin,
			packPtr->masterPtr->tkwin);
			packPtr->containerPtr->tkwin);
	    }
	    Unlink(packPtr);
	    Tk_UnmapWindow(packPtr->tkwin);
	}
	break;
    }
#endif /* !TK_NO_DEPRECATED */
515
516
517
518
519
520
521
522

523
524
525
526
527
528

529
530
531
532
533
534
535
536
537
538

539
540
541

542
543
544
545
546
547

548
549
550
551
552
553
554


555
556

557
558

559
560
561
562


563
564
565


566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582

583
584
585
586
587
588
589

590
591
592
593


594
595
596
597

598
599
600
601
602
603
604
605
606
607
608
609
610

611
612
613
614


615
616
617
618

619
620
621
622
623
624
625
626
627
628
629


630
631

632
633

634
635
636

637
638
639
640

641
642

643
644
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
515
516
517
518
519
520
521

522
523
524
525

526

527
528
529
530
531
532
533
534
535
536

537
538
539

540
541
542
543
544
545

546
547
548
549
550
551


552
553
554

555
556

557

558


559
560
561


562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579

580
581
582
583
584
585
586

587
588
589


590
591
592
593
594

595
596
597
598
599
600
601
602
603
604
605
606
607

608
609
610


611
612
613
614
615

616
617
618
619
620
621
622
623
624
625


626
627
628

629
630

631
632
633

634
635
636
637

638
639

640
641




642
643
644
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







-
+



-

-
+









-
+


-
+





-
+





-
-
+
+

-
+

-
+
-

-
-
+
+

-
-
+
+
















-
+






-
+


-
-
+
+



-
+












-
+


-
-
+
+



-
+









-
-
+
+

-
+

-
+


-
+



-
+

-
+

-
-
-
-
+
+
+
+




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



-
-
+
+

-
-
+
+



-
-
+
+









-
-
+
+

-
-
+
+



-
+


-
+


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




-
+







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

-
-
-
-
+
+
+
+







-
+







-
-
-
-
+
+
+
+







-
+
















-
+




-
-
-
+
+
+

-
+


-
-
-
+
+
+



-
-
-
+
+
+



-
+







 *------------------------------------------------------------------------
 */

static void
PackReqProc(
    ClientData clientData,	/* Packer's information about window that got
				 * new preferred geometry.  */
    Tk_Window tkwin)		/* Other Tk-related information about the
    TCL_UNUSED(Tk_Window))		/* Other Tk-related information about the
				 * window. */
{
    Packer *packPtr = (Packer *)clientData;
    (void)tkwin;

    packPtr = packPtr->masterPtr;
    packPtr = packPtr->containerPtr;
    if (!(packPtr->flags & REQUESTED_REPACK)) {
	packPtr->flags |= REQUESTED_REPACK;
	Tcl_DoWhenIdle(ArrangePacking, packPtr);
    }
}

/*
 *------------------------------------------------------------------------
 *
 * PackLostSlaveProc --
 * PackLostContentProc --
 *
 *	This function is invoked by Tk whenever some other geometry claims
 *	control over a slave that used to be managed by us.
 *	control over a content window that used to be managed by us.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Forgets all packer-related information about the slave.
 *	Forgets all packer-related information about the content.
 *
 *------------------------------------------------------------------------
 */

static void
PackLostSlaveProc(
    ClientData clientData,	/* Packer structure for slave window that was
PackLostContentProc(
    void *clientData,	/* Packer structure for content window that was
				 * stolen away. */
    Tk_Window tkwin)		/* Tk's handle for the slave window. */
    TCL_UNUSED(Tk_Window))		/* Tk's handle for the content window. */
{
    Packer *slavePtr = (Packer *)clientData;
    Packer *contentPtr = (Packer *)clientData;
    (void)tkwin;

    if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) {
	Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin);
    if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
	Tk_UnmaintainGeometry(contentPtr->tkwin, contentPtr->containerPtr->tkwin);
    }
    Unlink(slavePtr);
    Tk_UnmapWindow(slavePtr->tkwin);
    Unlink(contentPtr);
    Tk_UnmapWindow(contentPtr->tkwin);
}

/*
 *------------------------------------------------------------------------
 *
 * ArrangePacking --
 *
 *	This function is invoked (using the Tcl_DoWhenIdle mechanism) to
 *	re-layout a set of windows managed by the packer. It is invoked at
 *	idle time so that a series of packer requests can be merged into a
 *	single layout operation.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The packed slaves of masterPtr may get resized or moved.
 *	The packed content of containerPtr may get resized or moved.
 *
 *------------------------------------------------------------------------
 */

static void
ArrangePacking(
    ClientData clientData)	/* Structure describing master whose slaves
    ClientData clientData)	/* Structure describing container whose content
				 * are to be re-layed out. */
{
    Packer *masterPtr = (Packer *)clientData;
    Packer *slavePtr;
    Packer *containerPtr = (Packer *)clientData;
    Packer *contentPtr;
    int cavityX, cavityY, cavityWidth, cavityHeight;
				/* These variables keep track of the
				 * as-yet-unallocated space remaining in the
				 * middle of the master window. */
				 * middle of the container window. */
    int frameX, frameY, frameWidth, frameHeight;
				/* These variables keep track of the frame
				 * allocated to the current window. */
    int x, y, width, height;	/* These variables are used to hold the actual
				 * geometry of the current window. */
    int abort;			/* May get set to non-zero to abort this
				 * repacking operation. */
    int borderX, borderY;
    int borderTop, borderBtm;
    int borderLeft, borderRight;
    int maxWidth, maxHeight, tmp;

    masterPtr->flags &= ~REQUESTED_REPACK;
    containerPtr->flags &= ~REQUESTED_REPACK;

    /*
     * If the master has no slaves anymore, then leave the master's size as-is.
     * Otherwise there is no way to "relinquish" control over the master
     * If the container has no content anymore, then leave the container's size as-is.
     * Otherwise there is no way to "relinquish" control over the container
     * so another geometry manager can take over.
     */

    if (masterPtr->slavePtr == NULL) {
    if (containerPtr->contentPtr == NULL) {
	return;
    }

    /*
     * Abort any nested call to ArrangePacking for this window, since we'll do
     * everything necessary here, and set up so this call can be aborted if
     * necessary.
     */

    if (masterPtr->abortPtr != NULL) {
	*masterPtr->abortPtr = 1;
    if (containerPtr->abortPtr != NULL) {
	*containerPtr->abortPtr = 1;
    }
    masterPtr->abortPtr = &abort;
    containerPtr->abortPtr = &abort;
    abort = 0;
    Tcl_Preserve(masterPtr);
    Tcl_Preserve(containerPtr);

    /*
     * Pass #1: scan all the slaves to figure out the total amount of space
     * Pass #1: scan all the content to figure out the total amount of space
     * needed. Two separate width and height values are computed:
     *
     * width -		Holds the sum of the widths (plus padding) of all the
     *			slaves seen so far that were packed LEFT or RIGHT.
     *			content seen so far that were packed LEFT or RIGHT.
     * height -		Holds the sum of the heights (plus padding) of all the
     *			slaves seen so far that were packed TOP or BOTTOM.
     *			content seen so far that were packed TOP or BOTTOM.
     *
     * maxWidth -	Gradually builds up the width needed by the master to
     *			just barely satisfy all the slave's needs. For each
     *			slave, the code computes the width needed for all the
     *			slaves so far and updates maxWidth if the new value is
     * maxWidth -	Gradually builds up the width needed by the container to
     *			just barely satisfy all the content's needs. For each
     *			content, the code computes the width needed for all the
     *			content so far and updates maxWidth if the new value is
     *			greater.
     * maxHeight -	Same as maxWidth, except keeps height info.
     */

    width = maxWidth = Tk_InternalBorderLeft(masterPtr->tkwin) +
	    Tk_InternalBorderRight(masterPtr->tkwin);
    height = maxHeight = Tk_InternalBorderTop(masterPtr->tkwin) +
	    Tk_InternalBorderBottom(masterPtr->tkwin);
    for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
	    slavePtr = slavePtr->nextPtr) {
	if ((slavePtr->side == TOP) || (slavePtr->side == BOTTOM)) {
	    tmp = Tk_ReqWidth(slavePtr->tkwin) + slavePtr->doubleBw
		    + slavePtr->padX + slavePtr->iPadX + width;
    width = maxWidth = Tk_InternalBorderLeft(containerPtr->tkwin) +
	    Tk_InternalBorderRight(containerPtr->tkwin);
    height = maxHeight = Tk_InternalBorderTop(containerPtr->tkwin) +
	    Tk_InternalBorderBottom(containerPtr->tkwin);
    for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
	    contentPtr = contentPtr->nextPtr) {
	if ((contentPtr->side == TOP) || (contentPtr->side == BOTTOM)) {
	    tmp = Tk_ReqWidth(contentPtr->tkwin) + contentPtr->doubleBw
		    + contentPtr->padX + contentPtr->iPadX + width;
	    if (tmp > maxWidth) {
		maxWidth = tmp;
	    }
	    height += Tk_ReqHeight(slavePtr->tkwin) + slavePtr->doubleBw
		    + slavePtr->padY + slavePtr->iPadY;
	    height += Tk_ReqHeight(contentPtr->tkwin) + contentPtr->doubleBw
		    + contentPtr->padY + contentPtr->iPadY;
	} else {
	    tmp = Tk_ReqHeight(slavePtr->tkwin) + slavePtr->doubleBw
		    + slavePtr->padY + slavePtr->iPadY + height;
	    tmp = Tk_ReqHeight(contentPtr->tkwin) + contentPtr->doubleBw
		    + contentPtr->padY + contentPtr->iPadY + height;
	    if (tmp > maxHeight) {
		maxHeight = tmp;
	    }
	    width += Tk_ReqWidth(slavePtr->tkwin) + slavePtr->doubleBw
		    + slavePtr->padX + slavePtr->iPadX;
	    width += Tk_ReqWidth(contentPtr->tkwin) + contentPtr->doubleBw
		    + contentPtr->padX + contentPtr->iPadX;
	}
    }
    if (width > maxWidth) {
	maxWidth = width;
    }
    if (height > maxHeight) {
	maxHeight = height;
    }

    if (maxWidth < Tk_MinReqWidth(masterPtr->tkwin)) {
	maxWidth = Tk_MinReqWidth(masterPtr->tkwin);
    if (maxWidth < Tk_MinReqWidth(containerPtr->tkwin)) {
	maxWidth = Tk_MinReqWidth(containerPtr->tkwin);
    }
    if (maxHeight < Tk_MinReqHeight(masterPtr->tkwin)) {
	maxHeight = Tk_MinReqHeight(masterPtr->tkwin);
    if (maxHeight < Tk_MinReqHeight(containerPtr->tkwin)) {
	maxHeight = Tk_MinReqHeight(containerPtr->tkwin);
    }

    /*
     * If the total amount of space needed in the master window has changed,
     * If the total amount of space needed in the container window has changed,
     * and if we're propagating geometry information, then notify the next
     * geometry manager up and requeue ourselves to start again after the
     * master has had a chance to resize us.
     * container has had a chance to resize us.
     */

    if (((maxWidth != Tk_ReqWidth(masterPtr->tkwin))
	    || (maxHeight != Tk_ReqHeight(masterPtr->tkwin)))
	    && !(masterPtr->flags & DONT_PROPAGATE)) {
	Tk_GeometryRequest(masterPtr->tkwin, maxWidth, maxHeight);
	masterPtr->flags |= REQUESTED_REPACK;
	Tcl_DoWhenIdle(ArrangePacking, masterPtr);
    if (((maxWidth != Tk_ReqWidth(containerPtr->tkwin))
	    || (maxHeight != Tk_ReqHeight(containerPtr->tkwin)))
	    && !(containerPtr->flags & DONT_PROPAGATE)) {
	Tk_GeometryRequest(containerPtr->tkwin, maxWidth, maxHeight);
	containerPtr->flags |= REQUESTED_REPACK;
	Tcl_DoWhenIdle(ArrangePacking, containerPtr);
	goto done;
    }

    /*
     * Pass #2: scan the slaves a second time assigning new sizes. The
     * Pass #2: scan the content a second time assigning new sizes. The
     * "cavity" variables keep track of the unclaimed space in the cavity of
     * the window; this shrinks inward as we allocate windows around the
     * edges. The "frame" variables keep track of the space allocated to the
     * current window and its frame. The current window is then placed
     * somewhere inside the frame, depending on anchor.
     */

    cavityX = x = Tk_InternalBorderLeft(masterPtr->tkwin);
    cavityY = y = Tk_InternalBorderTop(masterPtr->tkwin);
    cavityWidth = Tk_Width(masterPtr->tkwin) -
	    Tk_InternalBorderLeft(masterPtr->tkwin) -
	    Tk_InternalBorderRight(masterPtr->tkwin);
    cavityHeight = Tk_Height(masterPtr->tkwin) -
	    Tk_InternalBorderTop(masterPtr->tkwin) -
	    Tk_InternalBorderBottom(masterPtr->tkwin);
    for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
	    slavePtr = slavePtr->nextPtr) {
	if ((slavePtr->side == TOP) || (slavePtr->side == BOTTOM)) {
    cavityX = x = Tk_InternalBorderLeft(containerPtr->tkwin);
    cavityY = y = Tk_InternalBorderTop(containerPtr->tkwin);
    cavityWidth = Tk_Width(containerPtr->tkwin) -
	    Tk_InternalBorderLeft(containerPtr->tkwin) -
	    Tk_InternalBorderRight(containerPtr->tkwin);
    cavityHeight = Tk_Height(containerPtr->tkwin) -
	    Tk_InternalBorderTop(containerPtr->tkwin) -
	    Tk_InternalBorderBottom(containerPtr->tkwin);
    for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
	    contentPtr = contentPtr->nextPtr) {
	if ((contentPtr->side == TOP) || (contentPtr->side == BOTTOM)) {
	    frameWidth = cavityWidth;
	    frameHeight = Tk_ReqHeight(slavePtr->tkwin) + slavePtr->doubleBw
		    + slavePtr->padY + slavePtr->iPadY;
	    if (slavePtr->flags & EXPAND) {
		frameHeight += YExpansion(slavePtr, cavityHeight);
	    frameHeight = Tk_ReqHeight(contentPtr->tkwin) + contentPtr->doubleBw
		    + contentPtr->padY + contentPtr->iPadY;
	    if (contentPtr->flags & EXPAND) {
		frameHeight += YExpansion(contentPtr, cavityHeight);
	    }
	    cavityHeight -= frameHeight;
	    if (cavityHeight < 0) {
		frameHeight += cavityHeight;
		cavityHeight = 0;
	    }
	    frameX = cavityX;
	    if (slavePtr->side == TOP) {
	    if (contentPtr->side == TOP) {
		frameY = cavityY;
		cavityY += frameHeight;
	    } else {
		frameY = cavityY + cavityHeight;
	    }
	} else {
	    frameHeight = cavityHeight;
	    frameWidth = Tk_ReqWidth(slavePtr->tkwin) + slavePtr->doubleBw
		    + slavePtr->padX + slavePtr->iPadX;
	    if (slavePtr->flags & EXPAND) {
		frameWidth += XExpansion(slavePtr, cavityWidth);
	    frameWidth = Tk_ReqWidth(contentPtr->tkwin) + contentPtr->doubleBw
		    + contentPtr->padX + contentPtr->iPadX;
	    if (contentPtr->flags & EXPAND) {
		frameWidth += XExpansion(contentPtr, cavityWidth);
	    }
	    cavityWidth -= frameWidth;
	    if (cavityWidth < 0) {
		frameWidth += cavityWidth;
		cavityWidth = 0;
	    }
	    frameY = cavityY;
	    if (slavePtr->side == LEFT) {
	    if (contentPtr->side == LEFT) {
		frameX = cavityX;
		cavityX += frameWidth;
	    } else {
		frameX = cavityX + cavityWidth;
	    }
	}

	/*
	 * Now that we've got the size of the frame for the window, compute
	 * the window's actual size and location using the fill, padding, and
	 * frame factors. The variables "borderX" and "borderY" are used to
	 * handle the differences between old-style packing and the new style
	 * (in old-style, iPadX and iPadY are always zero and padding is
	 * completely ignored except when computing frame size).
	 */

	if (slavePtr->flags & OLD_STYLE) {
	if (contentPtr->flags & OLD_STYLE) {
	    borderX = borderY = 0;
	    borderTop = borderBtm = 0;
	    borderLeft = borderRight = 0;
	} else {
	    borderX = slavePtr->padX;
	    borderY = slavePtr->padY;
	    borderLeft = slavePtr->padLeft;
	    borderX = contentPtr->padX;
	    borderY = contentPtr->padY;
	    borderLeft = contentPtr->padLeft;
	    borderRight = borderX - borderLeft;
	    borderTop = slavePtr->padTop;
	    borderTop = contentPtr->padTop;
	    borderBtm = borderY - borderTop;
	}
	width = Tk_ReqWidth(slavePtr->tkwin) + slavePtr->doubleBw
		+ slavePtr->iPadX;
	if ((slavePtr->flags & FILLX)
	width = Tk_ReqWidth(contentPtr->tkwin) + contentPtr->doubleBw
		+ contentPtr->iPadX;
	if ((contentPtr->flags & FILLX)
		|| (width > (frameWidth - borderX))) {
	    width = frameWidth - borderX;
	}
	height = Tk_ReqHeight(slavePtr->tkwin) + slavePtr->doubleBw
		+ slavePtr->iPadY;
	if ((slavePtr->flags & FILLY)
	height = Tk_ReqHeight(contentPtr->tkwin) + contentPtr->doubleBw
		+ contentPtr->iPadY;
	if ((contentPtr->flags & FILLY)
		|| (height > (frameHeight - borderY))) {
	    height = frameHeight - borderY;
	}
	switch (slavePtr->anchor) {
	switch (contentPtr->anchor) {
	case TK_ANCHOR_N:
	    x = frameX + (borderLeft + frameWidth - width - borderRight)/2;
	    y = frameY + borderTop;
	    break;
	case TK_ANCHOR_NE:
	    x = frameX + frameWidth - width - borderRight;
	    y = frameY + borderTop;
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
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







-
-
+
+



-
+



-
+

-
+

-
-
-
-
-
+
+
+
+
+






-
-
+
+


-
-
+
+




-
-
+
+

-
+
















-
-
+
+







-
+














-
+

-
+

















-
-
-
-
+
+
+
+








-
+


















-
+














-
+

-
+










-
-
-
-
+
+
+
+








-
+







	case TK_ANCHOR_CENTER:
	    x = frameX + (borderLeft + frameWidth - width - borderRight)/2;
	    y = frameY + (borderTop + frameHeight - height - borderBtm)/2;
	    break;
	default:
	    Tcl_Panic("bad frame factor in ArrangePacking");
	}
	width -= slavePtr->doubleBw;
	height -= slavePtr->doubleBw;
	width -= contentPtr->doubleBw;
	height -= contentPtr->doubleBw;

	/*
	 * The final step is to set the position, size, and mapped/unmapped
	 * state of the slave. If the slave is a child of the master, then do
	 * state of the content. If the content is a child of the container, then do
	 * this here. Otherwise let Tk_MaintainGeometry do the work.
	 */

	if (masterPtr->tkwin == Tk_Parent(slavePtr->tkwin)) {
	if (containerPtr->tkwin == Tk_Parent(contentPtr->tkwin)) {
	    if ((width <= 0) || (height <= 0)) {
		Tk_UnmapWindow(slavePtr->tkwin);
		Tk_UnmapWindow(contentPtr->tkwin);
	    } else {
		if ((x != Tk_X(slavePtr->tkwin))
			|| (y != Tk_Y(slavePtr->tkwin))
			|| (width != Tk_Width(slavePtr->tkwin))
			|| (height != Tk_Height(slavePtr->tkwin))) {
		    Tk_MoveResizeWindow(slavePtr->tkwin, x, y, width, height);
		if ((x != Tk_X(contentPtr->tkwin))
			|| (y != Tk_Y(contentPtr->tkwin))
			|| (width != Tk_Width(contentPtr->tkwin))
			|| (height != Tk_Height(contentPtr->tkwin))) {
		    Tk_MoveResizeWindow(contentPtr->tkwin, x, y, width, height);
		}
		if (abort) {
		    goto done;
		}

		/*
		 * Don't map the slave if the master isn't mapped: wait until
		 * the master gets mapped later.
		 * Don't map the content if the container isn't mapped: wait until
		 * the container gets mapped later.
		 */

		if (Tk_IsMapped(masterPtr->tkwin)) {
		    Tk_MapWindow(slavePtr->tkwin);
		if (Tk_IsMapped(containerPtr->tkwin)) {
		    Tk_MapWindow(contentPtr->tkwin);
		}
	    }
	} else {
	    if ((width <= 0) || (height <= 0)) {
		Tk_UnmaintainGeometry(slavePtr->tkwin, masterPtr->tkwin);
		Tk_UnmapWindow(slavePtr->tkwin);
		Tk_UnmaintainGeometry(contentPtr->tkwin, containerPtr->tkwin);
		Tk_UnmapWindow(contentPtr->tkwin);
	    } else {
		Tk_MaintainGeometry(slavePtr->tkwin, masterPtr->tkwin,
		Tk_MaintainGeometry(contentPtr->tkwin, containerPtr->tkwin,
			x, y, width, height);
	    }
	}

	/*
	 * Changes to the window's structure could cause almost anything to
	 * happen, including deleting the parent or child. If this happens,
	 * we'll be told to abort.
	 */

	if (abort) {
	    goto done;
	}
    }

  done:
    masterPtr->abortPtr = NULL;
    Tcl_Release(masterPtr);
    containerPtr->abortPtr = NULL;
    Tcl_Release(containerPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * XExpansion --
 *
 *	Given a list of packed slaves, the first of which is packed on the
 *	Given a list of packed content, the first of which is packed on the
 *	left or right and is expandable, compute how much to expand the child.
 *
 * Results:
 *	The return value is the number of additional pixels to give to the
 *	child.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
XExpansion(
    Packer *slavePtr,	/* First in list of remaining slaves. */
    Packer *contentPtr,	/* First in list of remaining content. */
    int cavityWidth)		/* Horizontal space left for all remaining
				 * slaves. */
				 * content. */
{
    int numExpand, minExpand, curExpand;
    int childWidth;

    /*
     * This function is tricky because windows packed top or bottom can be
     * interspersed among expandable windows packed left or right. Scan
     * through the list, keeping a running sum of the widths of all left and
     * right windows (actually, count the cavity space not allocated) and a
     * running count of all expandable left and right windows. At each top or
     * bottom window, and at the end of the list, compute the expansion factor
     * that seems reasonable at that point. Return the smallest factor seen at
     * any of these points.
     */

    minExpand = cavityWidth;
    numExpand = 0;
    for ( ; slavePtr != NULL; slavePtr = slavePtr->nextPtr) {
	childWidth = Tk_ReqWidth(slavePtr->tkwin) + slavePtr->doubleBw
		+ slavePtr->padX + slavePtr->iPadX;
	if ((slavePtr->side == TOP) || (slavePtr->side == BOTTOM)) {
    for ( ; contentPtr != NULL; contentPtr = contentPtr->nextPtr) {
	childWidth = Tk_ReqWidth(contentPtr->tkwin) + contentPtr->doubleBw
		+ contentPtr->padX + contentPtr->iPadX;
	if ((contentPtr->side == TOP) || (contentPtr->side == BOTTOM)) {
	    if (numExpand) {
		curExpand = (cavityWidth - childWidth)/numExpand;
		if (curExpand < minExpand) {
		    minExpand = curExpand;
		}
	    }
	} else {
	    cavityWidth -= childWidth;
	    if (slavePtr->flags & EXPAND) {
	    if (contentPtr->flags & EXPAND) {
		numExpand++;
	    }
	}
    }
    if (numExpand) {
	curExpand = cavityWidth/numExpand;
	if (curExpand < minExpand) {
	    minExpand = curExpand;
	}
    }
    return (minExpand < 0) ? 0 : minExpand;
}

/*
 *----------------------------------------------------------------------
 *
 * YExpansion --
 *
 *	Given a list of packed slaves, the first of which is packed on the top
 *	Given a list of packed content, the first of which is packed on the top
 *	or bottom and is expandable, compute how much to expand the child.
 *
 * Results:
 *	The return value is the number of additional pixels to give to the
 *	child.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
YExpansion(
    Packer *slavePtr,	/* First in list of remaining slaves. */
    Packer *contentPtr,	/* First in list of remaining content. */
    int cavityHeight)		/* Vertical space left for all remaining
				 * slaves. */
				 * content. */
{
    int numExpand, minExpand, curExpand;
    int childHeight;

    /*
     * See comments for XExpansion.
     */

    minExpand = cavityHeight;
    numExpand = 0;
    for ( ; slavePtr != NULL; slavePtr = slavePtr->nextPtr) {
	childHeight = Tk_ReqHeight(slavePtr->tkwin) + slavePtr->doubleBw
		+ slavePtr->padY + slavePtr->iPadY;
	if ((slavePtr->side == LEFT) || (slavePtr->side == RIGHT)) {
    for ( ; contentPtr != NULL; contentPtr = contentPtr->nextPtr) {
	childHeight = Tk_ReqHeight(contentPtr->tkwin) + contentPtr->doubleBw
		+ contentPtr->padY + contentPtr->iPadY;
	if ((contentPtr->side == LEFT) || (contentPtr->side == RIGHT)) {
	    if (numExpand) {
		curExpand = (cavityHeight - childHeight)/numExpand;
		if (curExpand < minExpand) {
		    minExpand = curExpand;
		}
	    }
	} else {
	    cavityHeight -= childHeight;
	    if (slavePtr->flags & EXPAND) {
	    if (contentPtr->flags & EXPAND) {
		numExpand++;
	    }
	}
    }
    if (numExpand) {
	curExpand = cavityHeight/numExpand;
	if (curExpand < minExpand) {
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
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







-
+

-
+




















-
+

















-
-
+
+







    hPtr = Tcl_CreateHashEntry(&dispPtr->packerHashTable, (char *) tkwin,
	    &isNew);
    if (!isNew) {
	return (Packer *)Tcl_GetHashValue(hPtr);
    }
    packPtr = (Packer *)ckalloc(sizeof(Packer));
    packPtr->tkwin = tkwin;
    packPtr->masterPtr = NULL;
    packPtr->containerPtr = NULL;
    packPtr->nextPtr = NULL;
    packPtr->slavePtr = NULL;
    packPtr->contentPtr = NULL;
    packPtr->side = TOP;
    packPtr->anchor = TK_ANCHOR_CENTER;
    packPtr->padX = packPtr->padY = 0;
    packPtr->padLeft = packPtr->padTop = 0;
    packPtr->iPadX = packPtr->iPadY = 0;
    packPtr->doubleBw = 2*Tk_Changes(tkwin)->border_width;
    packPtr->abortPtr = NULL;
    packPtr->flags = 0;
    Tcl_SetHashValue(hPtr, packPtr);
    Tk_CreateEventHandler(tkwin, StructureNotifyMask,
	    PackStructureProc, packPtr);
    return packPtr;
}

/*
 *------------------------------------------------------------------------
 *
 * PackAfter --
 *
 *	This function does most of the real work of adding one or more windows
 *	into the packing order for its master.
 *	into the packing order for its container.
 *
 * Results:
 *	A standard Tcl return value.
 *
 * Side effects:
 *	The geometry of the specified windows may change, both now and again
 *	in the future.
 *
 *------------------------------------------------------------------------
 */

#ifndef TK_NO_DEPRECATED
static int
PackAfter(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Packer *prevPtr,		/* Pack windows in argv just after this
				 * window; NULL means pack as first child of
				 * masterPtr. */
    Packer *masterPtr,		/* Master in which to pack windows. */
				 * containerPtr. */
    Packer *containerPtr,		/* Container in which to pack windows. */
    int objc,			/* Number of elements in objv. */
    Tcl_Obj *const objv[])	/* Array of lists, each containing 2 elements:
				 * window name and side against which to
				 * pack. */
{
    Packer *packPtr;
    Tk_Window tkwin, ancestor, parent;
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
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







-
+





-
+






-
-
+
+







-
+








	/*
	 * Find the packer for the window to be packed, and make sure that the
	 * window in which it will be packed is either its or a descendant of
	 * its parent.
	 */

	if (TkGetWindowFromObj(interp, masterPtr->tkwin, objv[0], &tkwin)
	if (TkGetWindowFromObj(interp, containerPtr->tkwin, objv[0], &tkwin)
		!= TCL_OK) {
	    return TCL_ERROR;
	}

	parent = Tk_Parent(tkwin);
	for (ancestor = masterPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
	for (ancestor = containerPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == parent) {
		break;
	    }
	    if (((Tk_FakeWin *) (ancestor))->flags & TK_TOP_HIERARCHY) {
	    badWindow:
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't pack %s inside %s", Tcl_GetString(objv[0]),
			Tk_PathName(masterPtr->tkwin)));
			"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 == masterPtr->tkwin) {
	if (tkwin == containerPtr->tkwin) {
	    goto badWindow;
	}
	packPtr = GetPacker(tkwin);

	/*
	 * Process options for this window.
	 */
1179
1180
1181
1182
1183
1184
1185
1186

1187
1188
1189
1190
1191
1192
1193
1177
1178
1179
1180
1181
1182
1183

1184
1185
1186
1187
1188
1189
1190
1191







-
+







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







-
-
-
+
+
+


-
+





-
+



-
+

-
-
+
+






-
-
+
+





-
+





-
+


-
-
+
+

-
-
-
+
+
+










-
+





-
+








-
+

-
-
+
+


-
-
+
+

-
+









-
-
-
+
+
+

-
-
+
+


-
+


-
+


-
+



-
-
-
-
+
+
+
+







	}

	if (packPtr != prevPtr) {
	    /*
	     * Unpack this window if it's currently packed.
	     */

	    if (packPtr->masterPtr != NULL) {
		if ((packPtr->masterPtr != masterPtr) &&
			(packPtr->masterPtr->tkwin
	    if (packPtr->containerPtr != NULL) {
		if ((packPtr->containerPtr != containerPtr) &&
			(packPtr->containerPtr->tkwin
			!= Tk_Parent(packPtr->tkwin))) {
		    Tk_UnmaintainGeometry(packPtr->tkwin,
			    packPtr->masterPtr->tkwin);
			    packPtr->containerPtr->tkwin);
		}
		Unlink(packPtr);
	    }

	    /*
	     * Add the window in the correct place in its master's packing
	     * Add the window in the correct place in its container's packing
	     * order, then make sure that the window is managed by us.
	     */

	    packPtr->masterPtr = masterPtr;
	    packPtr->containerPtr = containerPtr;
	    if (prevPtr == NULL) {
		packPtr->nextPtr = masterPtr->slavePtr;
		masterPtr->slavePtr = packPtr;
		packPtr->nextPtr = containerPtr->contentPtr;
		containerPtr->contentPtr = packPtr;
	    } else {
		packPtr->nextPtr = prevPtr->nextPtr;
		prevPtr->nextPtr = packPtr;
	    }
	    Tk_ManageGeometry(tkwin, &packerType, packPtr);

	    if (!(masterPtr->flags & DONT_PROPAGATE)) {
		if (TkSetGeometryMaster(interp, masterPtr->tkwin, "pack")
	    if (!(containerPtr->flags & DONT_PROPAGATE)) {
		if (TkSetGeometryContainer(interp, containerPtr->tkwin, "pack")
			!= TCL_OK) {
		    Tk_ManageGeometry(tkwin, NULL, NULL);
		    Unlink(packPtr);
		    return TCL_ERROR;
		}
		masterPtr->flags |= ALLOCED_MASTER;
		containerPtr->flags |= ALLOCED_CONTAINER;
	    }
	}
    }

    /*
     * Arrange for the master to be re-packed at the first idle moment.
     * Arrange for the container to be re-packed at the first idle moment.
     */

    if (masterPtr->abortPtr != NULL) {
	*masterPtr->abortPtr = 1;
    if (containerPtr->abortPtr != NULL) {
	*containerPtr->abortPtr = 1;
    }
    if (!(masterPtr->flags & REQUESTED_REPACK)) {
	masterPtr->flags |= REQUESTED_REPACK;
	Tcl_DoWhenIdle(ArrangePacking, masterPtr);
    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 master's list of slaves.
 *	Remove a packer from its container's list of content.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The master will be scheduled for repacking.
 *	The container will be scheduled for repacking.
 *
 *----------------------------------------------------------------------
 */

static void
Unlink(
    Packer *packPtr)	/* Window to unlink. */
{
    Packer *masterPtr, *packPtr2;
    Packer *containerPtr, *packPtr2;

    masterPtr = packPtr->masterPtr;
    if (masterPtr == NULL) {
    containerPtr = packPtr->containerPtr;
    if (containerPtr == NULL) {
	return;
    }
    if (masterPtr->slavePtr == packPtr) {
	masterPtr->slavePtr = packPtr->nextPtr;
    if (containerPtr->contentPtr == packPtr) {
	containerPtr->contentPtr = packPtr->nextPtr;
    } else {
	for (packPtr2 = masterPtr->slavePtr; ; packPtr2 = packPtr2->nextPtr) {
	for (packPtr2 = containerPtr->contentPtr; ; packPtr2 = packPtr2->nextPtr) {
	    if (packPtr2 == NULL) {
		Tcl_Panic("Unlink couldn't find previous window");
	    }
	    if (packPtr2->nextPtr == packPtr) {
		packPtr2->nextPtr = packPtr->nextPtr;
		break;
	    }
	}
    }
    if (!(masterPtr->flags & REQUESTED_REPACK)) {
	masterPtr->flags |= REQUESTED_REPACK;
	Tcl_DoWhenIdle(ArrangePacking, masterPtr);
    if (!(containerPtr->flags & REQUESTED_REPACK)) {
	containerPtr->flags |= REQUESTED_REPACK;
	Tcl_DoWhenIdle(ArrangePacking, containerPtr);
    }
    if (masterPtr->abortPtr != NULL) {
	*masterPtr->abortPtr = 1;
    if (containerPtr->abortPtr != NULL) {
	*containerPtr->abortPtr = 1;
    }

    packPtr->masterPtr = NULL;
    packPtr->containerPtr = NULL;

    /*
     * If we have emptied this master from slaves it means we are no longer
     * 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 master to inform it about there
     * Send the event "NoManagedChild" to the container to inform it about there
     * being no managed children inside it.
     */

    if ((masterPtr->slavePtr == NULL) && (masterPtr->flags & ALLOCED_MASTER)) {
	TkFreeGeometryMaster(masterPtr->tkwin, "pack");
	masterPtr->flags &= ~ALLOCED_MASTER;
	TkSendVirtualEvent(masterPtr->tkwin, "NoManagedChild", NULL);
    if ((containerPtr->contentPtr == NULL) && (containerPtr->flags & ALLOCED_CONTAINER)) {
	TkFreeGeometryContainer(containerPtr->tkwin, "pack");
	containerPtr->flags &= ~ALLOCED_CONTAINER;
	Tk_SendVirtualEvent(containerPtr->tkwin, "NoManagedChild", NULL);
    }

}

/*
 *----------------------------------------------------------------------
 *
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
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







-
+













-
+




-
+

-
+

-
-
+
+



-
+

-
+



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















-
-
+
+


-
+








-
+



-
+









-
+


-
-
+
+






-
+





-
+


-
+






-
-
-
+
+
+







 *	StructureNotify events.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	If a window was just deleted, clean up all its packer-related
 *	information. If it was just resized, repack its slaves, if any.
 *	information. If it was just resized, repack its content, if any.
 *
 *----------------------------------------------------------------------
 */

static void
PackStructureProc(
    ClientData clientData,	/* Our information about window referred to by
				 * eventPtr. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    Packer *packPtr = (Packer *)clientData;

    if (eventPtr->type == ConfigureNotify) {
	if ((packPtr->slavePtr != NULL)
	if ((packPtr->contentPtr != NULL)
		&& !(packPtr->flags & REQUESTED_REPACK)) {
	    packPtr->flags |= REQUESTED_REPACK;
	    Tcl_DoWhenIdle(ArrangePacking, packPtr);
	}
	if ((packPtr->masterPtr != NULL)
	if ((packPtr->containerPtr != NULL)
	        && (packPtr->doubleBw != 2*Tk_Changes(packPtr->tkwin)->border_width)) {
	    if (!(packPtr->masterPtr->flags & REQUESTED_REPACK)) {
	    if (!(packPtr->containerPtr->flags & REQUESTED_REPACK)) {
		packPtr->doubleBw = 2*Tk_Changes(packPtr->tkwin)->border_width;
		packPtr->masterPtr->flags |= REQUESTED_REPACK;
		Tcl_DoWhenIdle(ArrangePacking, packPtr->masterPtr);
		packPtr->containerPtr->flags |= REQUESTED_REPACK;
		Tcl_DoWhenIdle(ArrangePacking, packPtr->containerPtr);
	    }
	}
    } else if (eventPtr->type == DestroyNotify) {
	Packer *slavePtr, *nextPtr;
	Packer *contentPtr, *nextPtr;

	if (packPtr->masterPtr != NULL) {
	if (packPtr->containerPtr != NULL) {
	    Unlink(packPtr);
	}

	for (slavePtr = packPtr->slavePtr; slavePtr != NULL;
		slavePtr = nextPtr) {
	    Tk_ManageGeometry(slavePtr->tkwin, NULL, NULL);
	    Tk_UnmapWindow(slavePtr->tkwin);
	    slavePtr->masterPtr = NULL;
	    nextPtr = slavePtr->nextPtr;
	    slavePtr->nextPtr = NULL;
	for (contentPtr = packPtr->contentPtr; contentPtr != NULL;
		contentPtr = nextPtr) {
	    Tk_ManageGeometry(contentPtr->tkwin, NULL, NULL);
	    Tk_UnmapWindow(contentPtr->tkwin);
	    contentPtr->containerPtr = NULL;
	    nextPtr = contentPtr->nextPtr;
	    contentPtr->nextPtr = NULL;
	}

	if (packPtr->tkwin != NULL) {
	    TkDisplay *dispPtr = ((TkWindow *) packPtr->tkwin)->dispPtr;
            Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->packerHashTable,
		    packPtr->tkwin));
	}

	if (packPtr->flags & REQUESTED_REPACK) {
	    Tcl_CancelIdleCall(ArrangePacking, packPtr);
	}
	packPtr->tkwin = NULL;
	Tcl_EventuallyFree(packPtr, (Tcl_FreeProc *) DestroyPacker);
    } else if (eventPtr->type == MapNotify) {
	/*
	 * When a master gets mapped, must redo the geometry computation so
	 * that all of its slaves get remapped.
	 * When a container gets mapped, must redo the geometry computation so
	 * that all of its content get remapped.
	 */

	if ((packPtr->slavePtr != NULL)
	if ((packPtr->contentPtr != NULL)
		&& !(packPtr->flags & REQUESTED_REPACK)) {
	    packPtr->flags |= REQUESTED_REPACK;
	    Tcl_DoWhenIdle(ArrangePacking, packPtr);
	}
    } else if (eventPtr->type == UnmapNotify) {
	Packer *packPtr2;

	/*
	 * Unmap all of the slaves when the master gets unmapped, so that they
	 * Unmap all of the content when the container gets unmapped, so that they
	 * don't bother to keep redisplaying themselves.
	 */

	for (packPtr2 = packPtr->slavePtr; packPtr2 != NULL;
	for (packPtr2 = packPtr->contentPtr; packPtr2 != NULL;
	     packPtr2 = packPtr2->nextPtr) {
	    Tk_UnmapWindow(packPtr2->tkwin);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureSlaves --
 * ConfigureContent --
 *
 *	This implements the guts of the "pack configure" command. Given a list
 *	of slaves and configuration options, it arranges for the packer to
 *	manage the slaves and sets the specified options.
 *	of content and configuration options, it arranges for the packer to
 *	manage the content and sets the specified options.
 *
 * Results:
 *	TCL_OK is returned if all went well. Otherwise, TCL_ERROR is returned
 *	and the interp's result is set to contain an error message.
 *
 * Side effects:
 *	Slave windows get taken over by the packer.
 *	Content windows get taken over by the packer.
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureSlaves(
ConfigureContent(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Window tkwin,		/* Any window in application containing
				 * slaves. Used to look up slave names. */
				 * content. Used to look up content names. */
    int objc,			/* Number of elements in argv. */
    Tcl_Obj *const objv[])	/* Argument objects: contains one or more
				 * window names followed by any number of
				 * "option value" pairs. Caller must make sure
				 * that there is at least one window name. */
{
    Packer *masterPtr, *slavePtr, *prevPtr, *otherPtr;
    Tk_Window other, slave, parent, ancestor;
    TkWindow *master;
    Packer *containerPtr, *contentPtr, *prevPtr, *otherPtr;
    Tk_Window other, content, parent, ancestor;
    TkWindow *container;
    int i, j, numWindows, tmp, positionGiven;
    const char *string;
    static const char *const optionStrings[] = {
	"-after", "-anchor", "-before", "-expand", "-fill",
	"-in", "-ipadx", "-ipady", "-padx", "-pady", "-side", NULL };
    enum options {
	CONF_AFTER, CONF_ANCHOR, CONF_BEFORE, CONF_EXPAND, CONF_FILL,
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
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







-
-
-
-
+
+
+
+





-
+



-
+


-
+






-
-
+
+


-
+




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







	string = Tcl_GetString(objv[numWindows]);
	if (string[0] != '.') {
	    break;
	}
    }

    /*
     * Iterate over all of the slave windows, parsing the configuration
     * options for each slave. It's a bit wasteful to re-parse the options for
     * each slave, but things get too messy if we try to parse the arguments
     * just once at the beginning. For example, if a slave already is packed
     * Iterate over all of the content windows, parsing the configuration
     * options for each content. It's a bit wasteful to re-parse the options for
     * each content, but things get too messy if we try to parse the arguments
     * just once at the beginning. For example, if a content already is packed
     * we want to just change a few existing values without resetting
     * everything. If there are multiple windows, the -after, -before, and -in
     * options only get processed for the first window.
     */

    masterPtr = NULL;
    containerPtr = NULL;
    prevPtr = NULL;
    positionGiven = 0;
    for (j = 0; j < numWindows; j++) {
	if (TkGetWindowFromObj(interp, tkwin, objv[j], &slave) != TCL_OK) {
	if (TkGetWindowFromObj(interp, tkwin, objv[j], &content) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (Tk_TopWinHierarchy(slave)) {
	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;
	}
	slavePtr = GetPacker(slave);
	slavePtr->flags &= ~OLD_STYLE;
	contentPtr = GetPacker(content);
	contentPtr->flags &= ~OLD_STYLE;

	/*
	 * If the slave isn't currently packed, reset all of its configuration
	 * If the content isn't currently packed, reset all of its configuration
	 * information to default values (there could be old values left from
	 * a previous packing).
	 */

	if (slavePtr->masterPtr == NULL) {
	    slavePtr->side = TOP;
	    slavePtr->anchor = TK_ANCHOR_CENTER;
	    slavePtr->padX = slavePtr->padY = 0;
	    slavePtr->padLeft = slavePtr->padTop = 0;
	    slavePtr->iPadX = slavePtr->iPadY = 0;
	    slavePtr->flags &= ~(FILLX|FILLY|EXPAND);
	if (contentPtr->containerPtr == NULL) {
	    contentPtr->side = TOP;
	    contentPtr->anchor = TK_ANCHOR_CENTER;
	    contentPtr->padX = contentPtr->padY = 0;
	    contentPtr->padLeft = contentPtr->padTop = 0;
	    contentPtr->iPadX = contentPtr->iPadY = 0;
	    contentPtr->flags &= ~(FILLX|FILLY|EXPAND);
	}

	for (i = numWindows; i < objc; i+=2) {
	    if ((i+2) > objc) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"extra option \"%s\" (option with no value?)",
			Tcl_GetString(objv[i])));
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
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







-
+








-
+




-
+











-
+


-
-
+
+














-
+

-
+





-
+

-
+

-
+

-
+














-
-
+
+









-
+







-
+


-
+







-
+


-
-
+
+




-
-
+
+








-
+





-
+




-
-
+
+




-
+




-
-
+
+





-
+




-
-
+
+








-
-
+
+



-
-
+
+





-
-
+
+




-
+

-
+








-
-
-
+
+
+

-
-
+
+




-
-
+
+



-
+



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

-
+


-
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+


-
+



-
+



-
-
+
+

-
-
-
+
+
+












	    case CONF_AFTER:
		if (j == 0) {
		    if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other)
			    != TCL_OK) {
			return TCL_ERROR;
		    }
		    prevPtr = GetPacker(other);
		    if (prevPtr->masterPtr == NULL) {
		    if (prevPtr->containerPtr == NULL) {
		    notPacked:
			Tcl_SetObjResult(interp, Tcl_ObjPrintf(
				"window \"%s\" isn't packed",
				Tcl_GetString(objv[i+1])));
			Tcl_SetErrorCode(interp, "TK", "PACK", "NOT_PACKED",
				NULL);
			return TCL_ERROR;
		    }
		    masterPtr = prevPtr->masterPtr;
		    containerPtr = prevPtr->containerPtr;
		    positionGiven = 1;
		}
		break;
	    case CONF_ANCHOR:
		if (Tk_GetAnchorFromObj(interp, objv[i+1], &slavePtr->anchor)
		if (Tk_GetAnchorFromObj(interp, objv[i+1], &contentPtr->anchor)
			!= TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_BEFORE:
		if (j == 0) {
		    if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other)
			    != TCL_OK) {
			return TCL_ERROR;
		    }
		    otherPtr = GetPacker(other);
		    if (otherPtr->masterPtr == NULL) {
		    if (otherPtr->containerPtr == NULL) {
			goto notPacked;
		    }
		    masterPtr = otherPtr->masterPtr;
		    prevPtr = masterPtr->slavePtr;
		    containerPtr = otherPtr->containerPtr;
		    prevPtr = containerPtr->contentPtr;
		    if (prevPtr == otherPtr) {
			prevPtr = NULL;
		    } else {
			while (prevPtr->nextPtr != otherPtr) {
			    prevPtr = prevPtr->nextPtr;
			}
		    }
		    positionGiven = 1;
		}
		break;
	    case CONF_EXPAND:
		if (Tcl_GetBooleanFromObj(interp, objv[i+1], &tmp) != TCL_OK) {
		    return TCL_ERROR;
		}
		slavePtr->flags &= ~EXPAND;
		contentPtr->flags &= ~EXPAND;
		if (tmp) {
		    slavePtr->flags |= EXPAND;
		    contentPtr->flags |= EXPAND;
		}
		break;
	    case CONF_FILL:
		string = Tcl_GetString(objv[i+1]);
		if (strcmp(string, "none") == 0) {
		    slavePtr->flags &= ~(FILLX|FILLY);
		    contentPtr->flags &= ~(FILLX|FILLY);
		} else if (strcmp(string, "x") == 0) {
		    slavePtr->flags = (slavePtr->flags & ~FILLY) | FILLX;
		    contentPtr->flags = (contentPtr->flags & ~FILLY) | FILLX;
		} else if (strcmp(string, "y") == 0) {
		    slavePtr->flags = (slavePtr->flags & ~FILLX) | FILLY;
		    contentPtr->flags = (contentPtr->flags & ~FILLX) | FILLY;
		} else if (strcmp(string, "both") == 0) {
		    slavePtr->flags |= FILLX|FILLY;
		    contentPtr->flags |= FILLX|FILLY;
		} else {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad fill style \"%s\": must be "
			    "none, x, y, or both", string));
		    Tcl_SetErrorCode(interp, "TK", "VALUE", "FILL", NULL);
		    return TCL_ERROR;
		}
		break;
	    case CONF_IN:
		if (j == 0) {
		    if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other)
			    != TCL_OK) {
			return TCL_ERROR;
		    }
		    masterPtr = GetPacker(other);
		    prevPtr = masterPtr->slavePtr;
		    containerPtr = GetPacker(other);
		    prevPtr = containerPtr->contentPtr;
		    if (prevPtr != NULL) {
			while (prevPtr->nextPtr != NULL) {
			    prevPtr = prevPtr->nextPtr;
			}
		    }
		    positionGiven = 1;
		}
		break;
	    case CONF_IPADX:
		if ((Tk_GetPixelsFromObj(interp, slave, objv[i+1], &tmp)
		if ((Tk_GetPixelsFromObj(interp, content, objv[i+1], &tmp)
			!= TCL_OK) || (tmp < 0)) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad ipadx value \"%s\": must be positive screen"
			    " distance", Tcl_GetString(objv[i+1])));
		    Tcl_SetErrorCode(interp, "TK", "VALUE", "INT_PAD", NULL);
		    return TCL_ERROR;
		}
		slavePtr->iPadX = tmp * 2;
		contentPtr->iPadX = tmp * 2;
		break;
	    case CONF_IPADY:
		if ((Tk_GetPixelsFromObj(interp, slave, objv[i+1], &tmp)
		if ((Tk_GetPixelsFromObj(interp, content, objv[i+1], &tmp)
			!= TCL_OK) || (tmp < 0)) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad ipady value \"%s\": must be positive screen"
			    " distance", Tcl_GetString(objv[i+1])));
		    Tcl_SetErrorCode(interp, "TK", "VALUE", "INT_PAD", NULL);
		    return TCL_ERROR;
		}
		slavePtr->iPadY = tmp * 2;
		contentPtr->iPadY = tmp * 2;
		break;
	    case CONF_PADX:
		if (TkParsePadAmount(interp, slave, objv[i+1],
			&slavePtr->padLeft, &slavePtr->padX) != TCL_OK) {
		if (TkParsePadAmount(interp, content, objv[i+1],
			&contentPtr->padLeft, &contentPtr->padX) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_PADY:
		if (TkParsePadAmount(interp, slave, objv[i+1],
			&slavePtr->padTop, &slavePtr->padY) != TCL_OK) {
		if (TkParsePadAmount(interp, content, objv[i+1],
			&contentPtr->padTop, &contentPtr->padY) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_SIDE:
		if (Tcl_GetIndexFromObjStruct(interp, objv[i+1], sideNames,
			sizeof(char *), "side", TCL_EXACT, &side) != TCL_OK) {
		    return TCL_ERROR;
		}
		slavePtr->side = (Side) side;
		contentPtr->side = (Side) side;
		break;
	    }
	}

	/*
	 * If no position in a packing list was specified and the slave is
	 * If no position in a packing list was specified and the content is
	 * already packed, then leave it in its current location in its
	 * current packing list.
	 */

	if (!positionGiven && (slavePtr->masterPtr != NULL)) {
	    masterPtr = slavePtr->masterPtr;
	if (!positionGiven && (contentPtr->containerPtr != NULL)) {
	    containerPtr = contentPtr->containerPtr;
	    goto scheduleLayout;
	}

	/*
	 * If the slave is going to be put back after itself or the same -in
	 * If the content is going to be put back after itself or the same -in
	 * window is passed in again, then just skip the whole operation,
	 * since it won't work anyway.
	 */

	if (prevPtr == slavePtr) {
	    masterPtr = slavePtr->masterPtr;
	if (prevPtr == contentPtr) {
	    containerPtr = contentPtr->containerPtr;
	    goto scheduleLayout;
	}

	/*
	 * If none of the "-in", "-before", or "-after" options has been
	 * specified, arrange for the slave to go at the end of the order for
	 * specified, arrange for the content to go at the end of the order for
	 * its parent.
	 */

	if (!positionGiven) {
	    masterPtr = GetPacker(Tk_Parent(slave));
	    prevPtr = masterPtr->slavePtr;
	    containerPtr = GetPacker(Tk_Parent(content));
	    prevPtr = containerPtr->contentPtr;
	    if (prevPtr != NULL) {
		while (prevPtr->nextPtr != NULL) {
		    prevPtr = prevPtr->nextPtr;
		}
	    }
	}

	/*
	 * Make sure that the slave's parent is either the master or an
	 * ancestor of the master, and that the master and slave aren't the
	 * Make sure that the content's parent is either the container or an
	 * ancestor of the container, and that the container and content aren't the
	 * same.
	 */

	parent = Tk_Parent(slave);
	for (ancestor = masterPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
	parent = Tk_Parent(content);
	for (ancestor = containerPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == parent) {
		break;
	    }
	    if (Tk_TopWinHierarchy(ancestor)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't pack %s inside %s", Tcl_GetString(objv[j]),
			Tk_PathName(masterPtr->tkwin)));
			"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 (slave == masterPtr->tkwin) {
	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 (master = (TkWindow *)masterPtr->tkwin; master != NULL;
	     master = (TkWindow *)TkGetGeomMaster(master)) {
	    if (master == (TkWindow *)slave) {
	for (container = (TkWindow *)containerPtr->tkwin; container != NULL;
	     container = (TkWindow *)TkGetContainer(container)) {
	    if (container == (TkWindow *)content) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't put %s inside %s, would cause management loop",
	            Tcl_GetString(objv[j]), Tk_PathName(masterPtr->tkwin)));
		    "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 (masterPtr->tkwin != Tk_Parent(slave)) {
	    ((TkWindow *)slave)->maintainerPtr = (TkWindow *)masterPtr->tkwin;
	if (containerPtr->tkwin != Tk_Parent(content)) {
	    ((TkWindow *)content)->maintainerPtr = (TkWindow *)containerPtr->tkwin;
	}

	/*
	 * Unpack the slave if it's currently packed, then position it after
	 * Unpack the content if it's currently packed, then position it after
	 * prevPtr.
	 */

	if (slavePtr->masterPtr != NULL) {
	    if ((slavePtr->masterPtr != masterPtr) &&
		    (slavePtr->masterPtr->tkwin
		    != Tk_Parent(slavePtr->tkwin))) {
		Tk_UnmaintainGeometry(slavePtr->tkwin,
			slavePtr->masterPtr->tkwin);
	if (contentPtr->containerPtr != NULL) {
	    if ((contentPtr->containerPtr != containerPtr) &&
		    (contentPtr->containerPtr->tkwin
		    != Tk_Parent(contentPtr->tkwin))) {
		Tk_UnmaintainGeometry(contentPtr->tkwin,
			contentPtr->containerPtr->tkwin);
	    }
	    Unlink(slavePtr);
	    Unlink(contentPtr);
	}

	slavePtr->masterPtr = masterPtr;
	contentPtr->containerPtr = containerPtr;
	if (prevPtr == NULL) {
	    slavePtr->nextPtr = masterPtr->slavePtr;
	    masterPtr->slavePtr = slavePtr;
	    contentPtr->nextPtr = containerPtr->contentPtr;
	    containerPtr->contentPtr = contentPtr;
	} else {
	    slavePtr->nextPtr = prevPtr->nextPtr;
	    prevPtr->nextPtr = slavePtr;
	    contentPtr->nextPtr = prevPtr->nextPtr;
	    prevPtr->nextPtr = contentPtr;
	}
	Tk_ManageGeometry(slave, &packerType, slavePtr);
	prevPtr = slavePtr;
	Tk_ManageGeometry(content, &packerType, contentPtr);
	prevPtr = contentPtr;

	if (!(masterPtr->flags & DONT_PROPAGATE)) {
	    if (TkSetGeometryMaster(interp, masterPtr->tkwin, "pack")
	if (!(containerPtr->flags & DONT_PROPAGATE)) {
	    if (TkSetGeometryContainer(interp, containerPtr->tkwin, "pack")
		    != TCL_OK) {
		Tk_ManageGeometry(slave, NULL, NULL);
		Unlink(slavePtr);
		Tk_ManageGeometry(content, NULL, NULL);
		Unlink(contentPtr);
		return TCL_ERROR;
	    }
	    masterPtr->flags |= ALLOCED_MASTER;
	    containerPtr->flags |= ALLOCED_CONTAINER;
	}

	/*
	 * Arrange for the master to be re-packed at the first idle moment.
	 * Arrange for the container to be re-packed at the first idle moment.
	 */

    scheduleLayout:
	if (masterPtr->abortPtr != NULL) {
	    *masterPtr->abortPtr = 1;
	if (containerPtr->abortPtr != NULL) {
	    *containerPtr->abortPtr = 1;
	}
	if (!(masterPtr->flags & REQUESTED_REPACK)) {
	    masterPtr->flags |= REQUESTED_REPACK;
	    Tcl_DoWhenIdle(ArrangePacking, masterPtr);
	if (!(containerPtr->flags & REQUESTED_REPACK)) {
	    containerPtr->flags |= REQUESTED_REPACK;
	    Tcl_DoWhenIdle(ArrangePacking, containerPtr);
	}
    }
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkPanedWindow.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








-
-
+
+







/*
 * tkPanedWindow.c --
 *
 *	This module implements "paned window" widgets that are object based. A
 *	"paned window" is a widget that manages the geometry for some number
 *	of other widgets, placing a movable "sash" between them, which can be
 *	used to alter the relative sizes of adjacent widgets.
 *
 * Copyright (c) 1997 Sun Microsystems, Inc.
 * Copyright (c) 2000 Ajuba Solutions.
 * Copyright © 1997 Sun Microsystems, Inc.
 * Copyright © 2000 Ajuba Solutions.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "default.h"
66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81

82
83
84
85

86
87

88
89
90

91
92
93


94
95
96
97

98
99
100
101
102
103

104
105

106
107
108
109

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

125
126
127
128
129
130
131
66
67
68
69
70
71
72

73
74
75
76
77
78
79
80

81
82
83
84

85
86

87
88
89

90
91


92
93
94
95
96

97
98
99
100
101
102

103
104

105
106
107
108

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

124
125
126
127
128
129
130
131







-
+







-
+



-
+

-
+


-
+

-
-
+
+



-
+





-
+

-
+



-
+














-
+







    (((stretch) == STRETCH_ALWAYS) ||				\
     ((stretch) == STRETCH_FIRST && (index) == (first)) ||	\
     ((stretch) == STRETCH_LAST && (index) == (last)) ||	\
     ((stretch) == STRETCH_MIDDLE && (index) != (first) && (index) != (last)))

typedef struct {
    Tk_OptionTable pwOptions;	/* Token for paned window option table. */
    Tk_OptionTable slaveOpts;	/* Token for slave cget option table. */
    Tk_OptionTable paneOpts;	/* Token for pane cget option table. */
} OptionTables;

/*
 * One structure of the following type is kept for each window
 * managed by a paned window widget.
 */

typedef struct Slave {
typedef struct Pane {
    Tk_Window tkwin;		/* Window being managed. */
    int minSize;		/* Minimum size of this pane, on the relevant
				 * axis, in pixels. */
    int padx;			/* Additional padding requested for slave, in
    int padx;			/* Additional padding requested for pane, in
				 * the x dimension. */
    int pady;			/* Additional padding requested for slave, in
    int pady;			/* Additional padding requested for pane, in
				 * the y dimension. */
    Tcl_Obj *widthPtr, *heightPtr;
				/* Tcl_Obj rep's of slave width/height, to
				/* Tcl_Obj rep's of pane width/height, to
				 * allow for null values. */
    int width;			/* Slave width. */
    int height;			/* Slave height. */
    int width;			/* Pane width. */
    int height;			/* Pane height. */
    int sticky;			/* Sticky string. */
    int x, y;			/* Coordinates of the widget. */
    int paneWidth, paneHeight;	/* Pane dimensions (may be different from
				 * slave width/height). */
				 * pane width/height). */
    int sashx, sashy;		/* Coordinates of the sash of the right or
				 * bottom of this pane. */
    int markx, marky;		/* Coordinates of the last mark set for the
				 * sash. */
    int handlex, handley;	/* Coordinates of the sash handle. */
    enum stretch stretch;	/* Controls how slave grows/shrinks */
    enum stretch stretch;	/* Controls how pane grows/shrinks */
    int hide;			/* Controls visibility of pane */
    struct PanedWindow *masterPtr;
    struct PanedWindow *containerPtr;
				/* Paned window managing the window. */
    Tk_Window after;		/* Placeholder for parsing options. */
    Tk_Window before;		/* Placeholder for parsing options. */
} Slave;
} Pane;

/*
 * A data structure of the following type is kept for each paned window widget
 * managed by this file:
 */

typedef struct PanedWindow {
    Tk_Window tkwin;		/* Window that embodies the paned window. */
    Tk_Window proxywin;		/* Window for the resizing proxy. */
    Display *display;		/* X's token for the window's display. */
    Tcl_Interp *interp;		/* Interpreter associated with widget. */
    Tcl_Command widgetCmd;	/* Token for square's widget command. */
    Tk_OptionTable optionTable;	/* Token representing the configuration
				 * specifications. */
    Tk_OptionTable slaveOpts;	/* Token for slave cget table. */
    Tk_OptionTable paneOpts;	/* Token for pane cget table. */
    Tk_3DBorder background;	/* Background color. */
    int borderWidth;		/* Value of -borderwidth option. */
    int relief;			/* 3D border effect (TK_RELIEF_RAISED, etc) */
    Tcl_Obj *widthPtr;		/* Tcl_Obj rep for width. */
    Tcl_Obj *heightPtr;		/* Tcl_Obj rep for height. */
    int width, height;		/* Width and height of the widget. */
    enum orient orient;		/* Orientation of the widget. */
147
148
149
150
151
152
153
154
155
156



157
158
159
160
161
162
163
147
148
149
150
151
152
153



154
155
156
157
158
159
160
161
162
163







-
-
-
+
+
+







    GC gc;			/* Graphics context for copying from
				 * off-screen pixmap onto screen. */
    int proxyx, proxyy;		/* Proxy x,y coordinates. */
    Tk_3DBorder proxyBackground;/* Background color used to draw proxy. If NULL, use background. */
    Tcl_Obj *proxyBorderWidthPtr; /* Tcl_Obj rep for proxyBorderWidth */
    int proxyBorderWidth;	/* Borderwidth used to draw proxy. */
    int proxyRelief;		/* Relief used to draw proxy, if TK_RELIEF_NULL then use relief. */
    Slave **slaves;		/* Pointer to array of Slaves. */
    int numSlaves;		/* Number of slaves. */
    int sizeofSlaves;		/* Number of elements in the slaves array. */
    Pane **panes;		/* Pointer to array of Panes. */
    int numPanes;		/* Number of panes. */
    int sizeofPanes;		/* Number of elements in the panes array. */
    int flags;			/* Flags for widget; see below. */
} PanedWindow;

/*
 * Flags used for paned windows:
 *
 * REDRAW_PENDING:		Non-zero means a DoWhenIdle handler has been
196
197
198
199
200
201
202
203

204
205
206
207
208
209


210
211
212

213
214
215
216
217
218
219
220
221

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

237
238
239
240
241
242
243
244

245
246
247
248

249
250
251
252
253

254
255
256
257
258
259
260
261
262
263
264

265
266
267
268
269
270
271
196
197
198
199
200
201
202

203
204
205
206
207


208
209
210
211

212
213
214
215
216
217
218
219
220

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

236
237
238
239
240
241
242
243

244
245
246
247

248
249
250
251
252

253
254
255
256
257
258
259
260
261
262
263

264
265
266
267
268
269
270
271







-
+




-
-
+
+


-
+








-
+














-
+







-
+



-
+




-
+










-
+







			    XEvent *eventPtr);
static void		ProxyWindowEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		DisplayProxyWindow(ClientData clientData);
static void		PanedWindowWorldChanged(ClientData instanceData);
static int		PanedWindowWidgetObjCmd(ClientData clientData,
			    Tcl_Interp *, int objc, Tcl_Obj * const objv[]);
static void		PanedWindowLostSlaveProc(ClientData clientData,
static void		PanedWindowLostPaneProc(ClientData clientData,
			    Tk_Window tkwin);
static void		PanedWindowReqProc(ClientData clientData,
			    Tk_Window tkwin);
static void		ArrangePanes(ClientData clientData);
static void		Unlink(Slave *slavePtr);
static Slave *		GetPane(PanedWindow *pwPtr, Tk_Window tkwin);
static void		Unlink(Pane *panePtr);
static Pane *		GetPane(PanedWindow *pwPtr, Tk_Window tkwin);
static void		GetFirstLastVisiblePane(PanedWindow *pwPtr,
			    int *firstPtr, int *lastPtr);
static void		SlaveStructureProc(ClientData clientData,
static void		PaneStructureProc(ClientData clientData,
			    XEvent *eventPtr);
static int		PanedWindowSashCommand(PanedWindow *pwPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static int		PanedWindowProxyCommand(PanedWindow *pwPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static void		ComputeGeometry(PanedWindow *pwPtr);
static int		ConfigureSlaves(PanedWindow *pwPtr,
static int		ConfigurePanes(PanedWindow *pwPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static void		DestroyOptionTables(ClientData clientData,
			    Tcl_Interp *interp);
static int		SetSticky(ClientData clientData, Tcl_Interp *interp,
			    Tk_Window tkwin, Tcl_Obj **value, char *recordPtr,
			    TkSizeT internalOffset, char *oldInternalPtr,
			    int flags);
static Tcl_Obj *	GetSticky(ClientData clientData, Tk_Window tkwin,
			    char *recordPtr, TkSizeT internalOffset);
static void		RestoreSticky(ClientData clientData, Tk_Window tkwin,
			    char *internalPtr, char *oldInternalPtr);
static void		AdjustForSticky(int sticky, int cavityWidth,
			    int cavityHeight, int *xPtr, int *yPtr,
			    int *slaveWidthPtr, int *slaveHeightPtr);
			    int *paneWidthPtr, int *paneHeightPtr);
static void		MoveSash(PanedWindow *pwPtr, int sash, int diff);
static int		ObjectIsEmpty(Tcl_Obj *objPtr);
static void *	ComputeSlotAddress(void *recordPtr, TkSizeT offset);
static int		PanedWindowIdentifyCoords(PanedWindow *pwPtr,
			    Tcl_Interp *interp, int x, int y);

/*
 * Sashes are between panes only, so there is one less sash than slaves
 * Sashes are between panes only, so there is one less sash than panes
 */

#define ValidSashIndex(pwPtr, sash) \
	(((sash) >= 0) && ((sash) < ((pwPtr)->numSlaves-1)))
	(((sash) >= 0) && ((sash) < ((pwPtr)->numPanes-1)))

static const Tk_GeomMgr panedWindowMgrType = {
    "panedwindow",		/* name */
    PanedWindowReqProc,		/* requestProc */
    PanedWindowLostSlaveProc,	/* lostSlaveProc */
    PanedWindowLostPaneProc,	/* lostPaneProc */
};

/*
 * Information used for objv parsing.
 */

#define GEOMETRY		0x0001

/*
 * The following structure contains pointers to functions used for processing
 * the custom "-sticky" option for slave windows.
 * the custom "-sticky" option for panes.
 */

static const Tk_ObjCustomOption stickyOption = {
    "sticky",			/* name */
    SetSticky,			/* setProc */
    GetSticky,			/* getProc */
    RestoreSticky,		/* restoreProc */
330
331
332
333
334
335
336
337

338
339

340
341
342

343
344
345
346


347
348

349
350

351
352

353
354

355
356

357
358
359

360
361
362
363


364
365
366
367
368
369
370
330
331
332
333
334
335
336

337
338

339
340
341

342
343
344


345
346
347

348
349

350
351

352
353

354
355

356
357
358

359
360
361


362
363
364
365
366
367
368
369
370







-
+

-
+


-
+


-
-
+
+

-
+

-
+

-
+

-
+

-
+


-
+


-
-
+
+







	 0, 0, GEOMETRY},
    {TK_OPTION_PIXELS, "-width", "width", "Width",
	 DEF_PANEDWINDOW_WIDTH, offsetof(PanedWindow, widthPtr),
	 offsetof(PanedWindow, width), TK_OPTION_NULL_OK, 0, GEOMETRY},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

static const Tk_OptionSpec slaveOptionSpecs[] = {
static const Tk_OptionSpec paneOptionSpecs[] = {
    {TK_OPTION_WINDOW, "-after", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_AFTER, TCL_INDEX_NONE, offsetof(Slave, after),
	 DEF_PANEDWINDOW_PANE_AFTER, TCL_INDEX_NONE, offsetof(Pane, after),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_WINDOW, "-before", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_BEFORE, TCL_INDEX_NONE, offsetof(Slave, before),
	 DEF_PANEDWINDOW_PANE_BEFORE, TCL_INDEX_NONE, offsetof(Pane, before),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-height", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_HEIGHT, offsetof(Slave, heightPtr),
	 offsetof(Slave, height), TK_OPTION_NULL_OK, 0, 0},
	 DEF_PANEDWINDOW_PANE_HEIGHT, offsetof(Pane, heightPtr),
	 offsetof(Pane, height), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-hide", "hide", "Hide",
	 DEF_PANEDWINDOW_PANE_HIDE, TCL_INDEX_NONE, offsetof(Slave, hide), 0,0,GEOMETRY},
	 DEF_PANEDWINDOW_PANE_HIDE, TCL_INDEX_NONE, offsetof(Pane, hide), 0,0,GEOMETRY},
    {TK_OPTION_PIXELS, "-minsize", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_MINSIZE, TCL_INDEX_NONE, offsetof(Slave, minSize), 0, 0, 0},
	 DEF_PANEDWINDOW_PANE_MINSIZE, TCL_INDEX_NONE, offsetof(Pane, minSize), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_PADX, TCL_INDEX_NONE, offsetof(Slave, padx), 0, 0, 0},
	 DEF_PANEDWINDOW_PANE_PADX, TCL_INDEX_NONE, offsetof(Pane, padx), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_PADY, TCL_INDEX_NONE, offsetof(Slave, pady), 0, 0, 0},
	 DEF_PANEDWINDOW_PANE_PADY, TCL_INDEX_NONE, offsetof(Pane, pady), 0, 0, 0},
    {TK_OPTION_CUSTOM, "-sticky", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_STICKY, TCL_INDEX_NONE, offsetof(Slave, sticky), 0,
	 DEF_PANEDWINDOW_PANE_STICKY, TCL_INDEX_NONE, offsetof(Pane, sticky), 0,
	 &stickyOption, 0},
    {TK_OPTION_STRING_TABLE, "-stretch", "stretch", "Stretch",
	DEF_PANEDWINDOW_PANE_STRETCH, TCL_INDEX_NONE, offsetof(Slave, stretch), 0,
	DEF_PANEDWINDOW_PANE_STRETCH, TCL_INDEX_NONE, offsetof(Pane, stretch), 0,
	(ClientData) stretchStrings, 0},
    {TK_OPTION_PIXELS, "-width", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_WIDTH, offsetof(Slave, widthPtr),
	 offsetof(Slave, width), TK_OPTION_NULL_OK, 0, 0},
	 DEF_PANEDWINDOW_PANE_WIDTH, offsetof(Pane, widthPtr),
	 offsetof(Pane, width), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

/*
 *--------------------------------------------------------------
 *
 * Tk_PanedWindowObjCmd --
379
380
381
382
383
384
385
386

387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
379
380
381
382
383
384
385

386
387
388
389
390
391
392
393
394

395
396
397
398
399
400
401







-
+








-







 *	A new widget is created and configured.
 *
 *--------------------------------------------------------------
 */

int
Tk_PanedWindowObjCmd(
    ClientData dummy,	/* NULL. */
    TCL_UNUSED(ClientData),	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj * const objv[])	/* Argument objects. */
{
    PanedWindow *pwPtr;
    Tk_Window tkwin, parent;
    OptionTables *pwOpts;
    XSetWindowAttributes atts;
    (void)dummy;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
425
426
427
428
429
430
431
432

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

451
452
453
454
455
456
457
424
425
426
427
428
429
430

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

449
450
451
452
453
454
455
456







-
+

















-
+







		DestroyOptionTables, pwOpts);

	/*
	 * Create the paned window option tables.
	 */

	pwOpts->pwOptions = Tk_CreateOptionTable(interp, optionSpecs);
	pwOpts->slaveOpts = Tk_CreateOptionTable(interp, slaveOptionSpecs);
	pwOpts->paneOpts = Tk_CreateOptionTable(interp, paneOptionSpecs);
    }

    Tk_SetClass(tkwin, "Panedwindow");

    /*
     * Allocate and initialize the widget record.
     */

    pwPtr = (PanedWindow *)ckalloc(sizeof(PanedWindow));
    memset((void *)pwPtr, 0, (sizeof(PanedWindow)));
    pwPtr->tkwin = tkwin;
    pwPtr->display = Tk_Display(tkwin);
    pwPtr->interp = interp;
    pwPtr->widgetCmd = Tcl_CreateObjCommand(interp,
	    Tk_PathName(pwPtr->tkwin), PanedWindowWidgetObjCmd, pwPtr,
	    PanedWindowCmdDeletedProc);
    pwPtr->optionTable = pwOpts->pwOptions;
    pwPtr->slaveOpts = pwOpts->slaveOpts;
    pwPtr->paneOpts = pwOpts->paneOpts;
    pwPtr->relief = TK_RELIEF_RAISED;
    pwPtr->gc = NULL;
    pwPtr->cursor = NULL;
    pwPtr->sashCursor = NULL;

    /*
     * Keep a hold of the associated tkwin until we destroy the widget,
468
469
470
471
472
473
474
475

476
477
478
479
480
481
482
467
468
469
470
471
472
473

474
475
476
477
478
479
480
481







-
+








    Tk_CreateEventHandler(pwPtr->tkwin, ExposureMask|StructureNotifyMask,
	    PanedWindowEventProc, pwPtr);

    /*
     * Find the toplevel ancestor of the panedwindow, and make a proxy win as
     * a child of that window; this way the proxy can always float above
     * slaves in the panedwindow.
     * panes in the panedwindow.
     */

    parent = Tk_Parent(pwPtr->tkwin);
    while (!(Tk_IsTopLevel(parent))) {
	parent = Tk_Parent(parent);
	if (parent == NULL) {
	    parent = pwPtr->tkwin;
503
504
505
506
507
508
509
510

511
512
513
514
515
516
517
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, TkNewWindowObj(pwPtr->tkwin));
    Tcl_SetObjResult(interp, Tk_NewWindowObj(pwPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * PanedWindowWidgetObjCmd --
545
546
547
548
549
550
551
552

553
554
555

556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573

574
575
576
577
578
579
580
544
545
546
547
548
549
550

551
552
553

554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571

572
573
574
575
576
577
578
579







-
+


-
+

















-
+







    enum options {
	PW_ADD, PW_CGET, PW_CONFIGURE, PW_FORGET, PW_IDENTIFY, PW_PANECGET,
	PW_PANECONFIGURE, PW_PANES, PW_PROXY, PW_SASH
    };
    Tcl_Obj *resultObj;
    int index, count, i, x, y;
    Tk_Window tkwin;
    Slave *slavePtr;
    Pane *panePtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg...?");
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "command",
	    0, &index) != TCL_OK) {
	return TCL_ERROR;
    }

    Tcl_Preserve(pwPtr);

    switch ((enum options) index) {
    case PW_ADD:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "widget ?widget ...?");
	    result = TCL_ERROR;
	    break;
	}
	result = ConfigureSlaves(pwPtr, interp, objc, objv);
	result = ConfigurePanes(pwPtr, interp, objc, objv);
	break;

    case PW_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    result = TCL_ERROR;
	    break;
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620

621
622
623

624
625
626
627


628
629
630
631
632
633
634






635
636
637
638
639
640
641
600
601
602
603
604
605
606

607
608
609
610
611
612
613
614
615
616
617

618
619
620

621
622
623


624
625
626






627
628
629
630
631
632
633
634
635
636
637
638
639







-











-
+


-
+


-
-
+
+

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







	    }
	} else {
	    result = ConfigurePanedWindow(interp, pwPtr, objc - 2, objv + 2);
	}
	break;

    case PW_FORGET: {
	int i;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "widget ?widget ...?");
	    result = TCL_ERROR;
	    break;
	}

	/*
	 * Clean up each window named in the arg list.
	 */
	for (count = 0, i = 2; i < objc; i++) {
	    Tk_Window slave = Tk_NameToWindow(interp, Tcl_GetString(objv[i]),
	    Tk_Window pane = Tk_NameToWindow(interp, Tcl_GetString(objv[i]),
		    pwPtr->tkwin);

	    if (slave == NULL) {
	    if (pane == NULL) {
		continue;
	    }
	    slavePtr = GetPane(pwPtr, slave);
	    if ((slavePtr != NULL) && (slavePtr->masterPtr != NULL)) {
	    panePtr = GetPane(pwPtr, pane);
	    if ((panePtr != NULL) && (panePtr->containerPtr != NULL)) {
		count++;
		Tk_ManageGeometry(slave, NULL, NULL);
		Tk_UnmaintainGeometry(slavePtr->tkwin, pwPtr->tkwin);
		Tk_DeleteEventHandler(slavePtr->tkwin, StructureNotifyMask,
			SlaveStructureProc, slavePtr);
		Tk_UnmapWindow(slavePtr->tkwin);
		Unlink(slavePtr);
		Tk_ManageGeometry(pane, NULL, NULL);
		Tk_UnmaintainGeometry(panePtr->tkwin, pwPtr->tkwin);
		Tk_DeleteEventHandler(panePtr->tkwin, StructureNotifyMask,
			PaneStructureProc, panePtr);
		Tk_UnmapWindow(panePtr->tkwin);
		Unlink(panePtr);
	    }
	    if (count != 0) {
		ComputeGeometry(pwPtr);
	    }
	}
	break;
    }
663
664
665
666
667
668
669
670
671


672
673

674
675
676
677
678

679
680
681
682
683
684
685
686
687
688
689
690
691
692
693

694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711


712
713

714
715
716
717
718
719
720
721
722
723
724
725

726
727
728
729
730
731

732
733

734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753

754
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
661
662
663
664
665
666
667


668
669
670

671
672
673
674
675

676
677
678
679
680
681
682
683
684
685
686
687
688
689
690

691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707


708
709
710

711
712
713
714
715
716
717
718
719
720
721
722

723
724
725
726
727
728

729
730

731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750

751
752

753
754
755
756
757
758


759
760
761
762
763
764
765

766
767
768
769
770
771

772
773
774


775
776
777
778
779
780

781
782
783
784
785
786
787
788







-
-
+
+

-
+




-
+














-
+
















-
-
+
+

-
+











-
+





-
+

-
+



















-
+

-
+





-
-
+
+





-
+





-
+


-
-
+
+




-
+







	}
	tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), pwPtr->tkwin);
	if (tkwin == NULL) {
	    result = TCL_ERROR;
	    break;
	}
	resultObj = NULL;
	for (i = 0; i < pwPtr->numSlaves; i++) {
	    if (pwPtr->slaves[i]->tkwin == tkwin) {
	for (i = 0; i < pwPtr->numPanes; i++) {
	    if (pwPtr->panes[i]->tkwin == tkwin) {
		resultObj = Tk_GetOptionValue(interp,
			pwPtr->slaves[i], pwPtr->slaveOpts,
			pwPtr->panes[i], pwPtr->paneOpts,
			objv[3], tkwin);
	    }
	}
	if (resultObj == NULL) {
	    if (i == pwPtr->numSlaves) {
	    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 option value ...?");
		    "pane ?-option value ...?");
	    result = TCL_ERROR;
	    break;
	}
	resultObj = NULL;
	if (objc <= 4) {
	    tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]),
		    pwPtr->tkwin);
            if (tkwin == NULL) {
                /*
                 * Just a plain old bad window; Tk_NameToWindow filled in an
                 * error message for us.
                 */

                result = TCL_ERROR;
                break;
            }
	    for (i = 0; i < pwPtr->numSlaves; i++) {
		if (pwPtr->slaves[i]->tkwin == tkwin) {
	    for (i = 0; i < pwPtr->numPanes; i++) {
		if (pwPtr->panes[i]->tkwin == tkwin) {
		    resultObj = Tk_GetOptionInfo(interp,
			    pwPtr->slaves[i], pwPtr->slaveOpts,
			    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 = ConfigureSlaves(pwPtr, interp, objc, objv);
	    result = ConfigurePanes(pwPtr, interp, objc, objv);
	}
	break;

    case PW_PANES:
	resultObj = Tcl_NewObj();
	for (i = 0; i < pwPtr->numSlaves; i++) {
	for (i = 0; i < pwPtr->numPanes; i++) {
	    Tcl_ListObjAppendElement(NULL, resultObj,
		    TkNewWindowObj(pwPtr->slaves[i]->tkwin));
		    Tk_NewWindowObj(pwPtr->panes[i]->tkwin));
	}
	Tcl_SetObjResult(interp, resultObj);
	break;

    case PW_PROXY:
	result = PanedWindowProxyCommand(pwPtr, interp, objc, objv);
	break;

    case PW_SASH:
	result = PanedWindowSashCommand(pwPtr, interp, objc, objv);
	break;
    }
    Tcl_Release(pwPtr);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureSlaves --
 * ConfigurePanes --
 *
 *	Add or alter the configuration options of a slave in a paned window.
 *	Add or alter the configuration options of a pane in a paned window.
 *
 * Results:
 *	Standard Tcl result.
 *
 * Side effects:
 *	Depends on options; may add a slave to the paned window, may alter the
 *	geometry management options of a slave.
 *	Depends on options; may add a pane to the paned window, may alter the
 *	geometry management options of a pane.
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureSlaves(
ConfigurePanes(
    PanedWindow *pwPtr,		/* Information about paned window. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int i, firstOptionArg, j, found, doubleBw, index, numNewSlaves, haveLoc;
    int i, firstOptionArg, j, found, doubleBw, index, numNewPanes, haveLoc;
    int insertIndex;
    Tk_Window tkwin = NULL, ancestor, parent;
    Slave *slavePtr, **inserts, **newSlaves;
    Slave options;
    Pane *panePtr, **inserts, **newPanes;
    Pane options;
    const char *arg;

    /*
     * Find the non-window name arguments; these are the configure options for
     * the slaves. Also validate that the window names given are legitimate
     * the panes. Also validate that the window names given are legitimate
     * (ie, they are real windows, they are not the panedwindow itself, etc.).
     */

    for (i = 2; i < objc; i++) {
	arg = Tcl_GetString(objv[i]);
	if (arg[0] == '-') {
	    break;
814
815
816
817
818
819
820
821
822


823
824
825
826
827
828
829
812
813
814
815
816
817
818


819
820
821
822
823
824
825
826
827







-
-
+
+







		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't add toplevel %s to %s", arg,
			Tk_PathName(pwPtr->tkwin)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "TOPLEVEL", NULL);
		return TCL_ERROR;
	    } else {
		/*
		 * Make sure the panedwindow is the parent of the slave,
		 * or a descendant of the slave's parent.
		 * Make sure the panedwindow is the parent of the pane,
		 * or a descendant of the pane's parent.
		 */

		parent = Tk_Parent(tkwin);
		for (ancestor = pwPtr->tkwin;;ancestor = Tk_Parent(ancestor)) {
		    if (ancestor == parent) {
			break;
		    }
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
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







-
-
+
+
















-
-
+
+







-
-
+
+
















-
+





-
+




-
+



-
+

-
-
+
+


-
+









-
-
-
-
+
+
+
+

-
-
+
+




-
+




-
-
+
+










-
+














-
+



-
-
-
+
+
+

-
+


-
-
-
-
-
+
+
+
+
+

-
+

-
-
+
+

-
+

-
-
+
+



-
+


-
-
-
-
-
+
+
+
+
+



-
+


-
-
-
+
+
+


-
+


-
-
-
-
+
+
+
+


-
+

-
+

-
+




-
-
+
+




-
+


-
-
-
+
+
+






-
+


-
+

-
+


-
+


-
+

-
+







    /*
     * Pre-parse the configuration options, to get the before/after specifiers
     * into an easy-to-find location (a local variable). Also, check the
     * return from Tk_SetOptions once, here, so we can save a little bit of
     * extra testing in the for loop below.
     */

    memset((void *)&options, 0, sizeof(Slave));
    if (Tk_SetOptions(interp, &options, pwPtr->slaveOpts,
    memset((void *)&options, 0, sizeof(Pane));
    if (Tk_SetOptions(interp, &options, pwPtr->paneOpts,
	    objc - firstOptionArg, objv + firstOptionArg,
	    pwPtr->tkwin, NULL, NULL) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * If either -after or -before was given, find the numerical index that
     * corresponds to the given window. If both -after and -before are given,
     * the option precedence is: -after, then -before.
     */

    index = -1;
    haveLoc = 0;
    if (options.after != NULL) {
	tkwin = options.after;
	haveLoc = 1;
	for (i = 0; i < pwPtr->numSlaves; i++) {
	    if (options.after == pwPtr->slaves[i]->tkwin) {
	for (i = 0; i < pwPtr->numPanes; i++) {
	    if (options.after == pwPtr->panes[i]->tkwin) {
		index = i + 1;
		break;
	    }
	}
    } else if (options.before != NULL) {
	tkwin = options.before;
	haveLoc = 1;
	for (i = 0; i < pwPtr->numSlaves; i++) {
	    if (options.before == pwPtr->slaves[i]->tkwin) {
	for (i = 0; i < pwPtr->numPanes; i++) {
	    if (options.before == pwPtr->panes[i]->tkwin) {
		index = i;
		break;
	    }
	}
    }

    /*
     * If a window was given for -after/-before, but it's not a window managed
     * by the panedwindow, throw an error
     */

    if (haveLoc && index == -1) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"window \"%s\" is not managed by %s",
		Tk_PathName(tkwin), Tk_PathName(pwPtr->tkwin)));
	Tcl_SetErrorCode(interp, "TK", "PANEDWINDOW", "UNMANAGED", NULL);
	Tk_FreeConfigOptions((char *) &options, pwPtr->slaveOpts,
	Tk_FreeConfigOptions((char *) &options, pwPtr->paneOpts,
		pwPtr->tkwin);
	return TCL_ERROR;
    }

    /*
     * Allocate an array to hold, in order, the pointers to the slave
     * Allocate an array to hold, in order, the pointers to the pane
     * structures corresponding to the windows specified. Some of those
     * structures may already have existed, some may be new.
     */

    inserts = (Slave **)ckalloc(sizeof(Slave *) * (firstOptionArg - 2));
    inserts = (Pane **)ckalloc(sizeof(Pane *) * (firstOptionArg - 2));
    insertIndex = 0;

    /*
     * Populate the inserts array, creating new slave structures as necessary,
     * Populate the inserts array, creating new pane structures as necessary,
     * applying the options to each structure as we go, and, if necessary,
     * marking the spot in the original slaves array as empty (for
     * pre-existing slave structures).
     * marking the spot in the original panes array as empty (for
     * pre-existing pane structures).
     */

    for (i = 0, numNewSlaves = 0; i < firstOptionArg - 2; i++) {
    for (i = 0, numNewPanes = 0; i < firstOptionArg - 2; i++) {
	/*
	 * We don't check that tkwin is NULL here, because the pre-pass above
	 * guarantees that the input at this stage is good.
	 */

	tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[i + 2]),
		pwPtr->tkwin);

	found = 0;
	for (j = 0; j < pwPtr->numSlaves; j++) {
	    if (pwPtr->slaves[j] != NULL && pwPtr->slaves[j]->tkwin == tkwin) {
		Tk_SetOptions(interp, pwPtr->slaves[j],
			pwPtr->slaveOpts, objc - firstOptionArg,
	for (j = 0; j < pwPtr->numPanes; j++) {
	    if (pwPtr->panes[j] != NULL && pwPtr->panes[j]->tkwin == tkwin) {
		Tk_SetOptions(interp, pwPtr->panes[j],
			pwPtr->paneOpts, objc - firstOptionArg,
			objv + firstOptionArg, pwPtr->tkwin, NULL, NULL);
		if (pwPtr->slaves[j]->minSize < 0) {
		    pwPtr->slaves[j]->minSize = 0;
		if (pwPtr->panes[j]->minSize < 0) {
		    pwPtr->panes[j]->minSize = 0;
		}
		found = 1;

		/*
		 * If the slave is supposed to move, add it to the inserts
		 * If the pane is supposed to move, add it to the inserts
		 * array now; otherwise, leave it where it is.
		 */

		if (index != -1) {
		    inserts[insertIndex++] = pwPtr->slaves[j];
		    pwPtr->slaves[j] = NULL;
		    inserts[insertIndex++] = pwPtr->panes[j];
		    pwPtr->panes[j] = NULL;
		}
		break;
	    }
	}

	if (found) {
	    continue;
	}

	/*
	 * Make sure this slave wasn't already put into the inserts array,
	 * Make sure this pane wasn't already put into the inserts array,
	 * i.e., when the user specifies the same window multiple times in a
	 * single add commaned.
	 */
	for (j = 0; j < insertIndex; j++) {
	    if (inserts[j]->tkwin == tkwin) {
		found = 1;
		break;
	    }
	}
	if (found) {
	    continue;
	}

	/*
	 * Create a new slave structure and initialize it. All slaves start
	 * Create a new pane structure and initialize it. All panes start
	 * out with their "natural" dimensions.
	 */

	slavePtr = (Slave *)ckalloc(sizeof(Slave));
	memset(slavePtr, 0, sizeof(Slave));
	Tk_InitOptions(interp, slavePtr, pwPtr->slaveOpts,
	panePtr = (Pane *)ckalloc(sizeof(Pane));
	memset(panePtr, 0, sizeof(Pane));
	Tk_InitOptions(interp, panePtr, pwPtr->paneOpts,
		pwPtr->tkwin);
	Tk_SetOptions(interp, slavePtr, pwPtr->slaveOpts,
	Tk_SetOptions(interp, panePtr, pwPtr->paneOpts,
		objc - firstOptionArg, objv + firstOptionArg,
		pwPtr->tkwin, NULL, NULL);
	slavePtr->tkwin = tkwin;
	slavePtr->masterPtr = pwPtr;
	doubleBw = 2 * Tk_Changes(slavePtr->tkwin)->border_width;
	if (slavePtr->width > 0) {
	    slavePtr->paneWidth = slavePtr->width;
	panePtr->tkwin = tkwin;
	panePtr->containerPtr = pwPtr;
	doubleBw = 2 * Tk_Changes(panePtr->tkwin)->border_width;
	if (panePtr->width > 0) {
	    panePtr->paneWidth = panePtr->width;
	} else {
	    slavePtr->paneWidth = Tk_ReqWidth(tkwin) + doubleBw;
	    panePtr->paneWidth = Tk_ReqWidth(tkwin) + doubleBw;
	}
	if (slavePtr->height > 0) {
	    slavePtr->paneHeight = slavePtr->height;
	if (panePtr->height > 0) {
	    panePtr->paneHeight = panePtr->height;
	} else {
	    slavePtr->paneHeight = Tk_ReqHeight(tkwin) + doubleBw;
	    panePtr->paneHeight = Tk_ReqHeight(tkwin) + doubleBw;
	}
	if (slavePtr->minSize < 0) {
	    slavePtr->minSize = 0;
	if (panePtr->minSize < 0) {
	    panePtr->minSize = 0;
	}

	/*
	 * Set up the geometry management callbacks for this slave.
	 * Set up the geometry management callbacks for this pane.
	 */

	Tk_CreateEventHandler(slavePtr->tkwin, StructureNotifyMask,
		SlaveStructureProc, slavePtr);
	Tk_ManageGeometry(slavePtr->tkwin, &panedWindowMgrType, slavePtr);
	inserts[insertIndex++] = slavePtr;
	numNewSlaves++;
	Tk_CreateEventHandler(panePtr->tkwin, StructureNotifyMask,
		PaneStructureProc, panePtr);
	Tk_ManageGeometry(panePtr->tkwin, &panedWindowMgrType, panePtr);
	inserts[insertIndex++] = panePtr;
	numNewPanes++;
    }

    /*
     * Allocate the new slaves array, then copy the slaves into it, in order.
     * Allocate the new panes array, then copy the panes into it, in order.
     */

    i = sizeof(Slave *) * (pwPtr->numSlaves + numNewSlaves);
    newSlaves = (Slave **)ckalloc(i);
    memset(newSlaves, 0, i);
    i = sizeof(Pane *) * (pwPtr->numPanes + numNewPanes);
    newPanes = (Pane **)ckalloc(i);
    memset(newPanes, 0, i);
    if (index == -1) {
	/*
	 * If none of the existing slaves have to be moved, just copy the old
	 * If none of the existing panes have to be moved, just copy the old
	 * and append the new.
	 */
	memcpy((void *)&(newSlaves[0]), pwPtr->slaves,
		sizeof(Slave *) * pwPtr->numSlaves);
	memcpy((void *)&(newSlaves[pwPtr->numSlaves]), inserts,
		sizeof(Slave *) * numNewSlaves);
	memcpy((void *)&(newPanes[0]), pwPtr->panes,
		sizeof(Pane *) * pwPtr->numPanes);
	memcpy((void *)&(newPanes[pwPtr->numPanes]), inserts,
		sizeof(Pane *) * numNewPanes);
    } else {
	/*
	 * If some of the existing slaves were moved, the old slaves array
	 * 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 slaves
	 * 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
	 * slaves, copy the inserts array over, then finish off the old slaves
	 * panes, copy the inserts array over, then finish off the old panes
	 * array.
	 */

	for (i = 0, j = 0; i < index; i++) {
	    if (pwPtr->slaves[i] != NULL) {
		newSlaves[j] = pwPtr->slaves[i];
	    if (pwPtr->panes[i] != NULL) {
		newPanes[j] = pwPtr->panes[i];
		j++;
	    }
	}

	memcpy((void *)&(newSlaves[j]), inserts, sizeof(Slave *)*insertIndex);
	memcpy((void *)&(newPanes[j]), inserts, sizeof(Pane *)*insertIndex);
	j += firstOptionArg - 2;

	for (i = index; i < pwPtr->numSlaves; i++) {
	    if (pwPtr->slaves[i] != NULL) {
		newSlaves[j] = pwPtr->slaves[i];
	for (i = index; i < pwPtr->numPanes; i++) {
	    if (pwPtr->panes[i] != NULL) {
		newPanes[j] = pwPtr->panes[i];
		j++;
	    }
	}
    }

    /*
     * Make the new slaves array the paned window's slave array, and clean up.
     * Make the new panes array the paned window's pane array, and clean up.
     */

    ckfree(pwPtr->slaves);
    ckfree(pwPtr->panes);
    ckfree(inserts);
    pwPtr->slaves = newSlaves;
    pwPtr->panes = newPanes;

    /*
     * Set the paned window's slave count to the new value.
     * Set the paned window's pane count to the new value.
     */

    pwPtr->numSlaves += numNewSlaves;
    pwPtr->numPanes += numNewPanes;

    Tk_FreeConfigOptions((char *) &options, pwPtr->slaveOpts, pwPtr->tkwin);
    Tk_FreeConfigOptions((char *) &options, pwPtr->paneOpts, pwPtr->tkwin);

    ComputeGeometry(pwPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
1098
1099
1100
1101
1102
1103
1104
1105

1106
1107
1108
1109
1110
1111
1112
1096
1097
1098
1099
1100
1101
1102

1103
1104
1105
1106
1107
1108
1109
1110







-
+







	"coord", "dragto", "mark", "place", NULL
    };
    enum sashOptions {
	SASH_COORD, SASH_DRAGTO, SASH_MARK, SASH_PLACE
    };
    int index, sash, x, y, diff;
    Tcl_Obj *coords[2];
    Slave *slavePtr;
    Pane *panePtr;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[2], sashOptionStrings, "option", 0,
1127
1128
1129
1130
1131
1132
1133
1134

1135
1136
1137


1138
1139
1140
1141
1142
1143
1144
1125
1126
1127
1128
1129
1130
1131

1132
1133


1134
1135
1136
1137
1138
1139
1140
1141
1142







-
+

-
-
+
+








	if (!ValidSashIndex(pwPtr, sash)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "invalid sash index", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "SASH_INDEX", NULL);
	    return TCL_ERROR;
	}
	slavePtr = pwPtr->slaves[sash];
	panePtr = pwPtr->panes[sash];

	coords[0] = Tcl_NewWideIntObj(slavePtr->sashx);
	coords[1] = Tcl_NewWideIntObj(slavePtr->sashy);
	coords[0] = Tcl_NewWideIntObj(panePtr->sashx);
	coords[1] = Tcl_NewWideIntObj(panePtr->sashy);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, coords));
	break;

    case SASH_MARK:
	if (objc != 6 && objc != 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index ?x y?");
	    return TCL_ERROR;
1160
1161
1162
1163
1164
1165
1166
1167
1168


1169
1170
1171


1172
1173
1174
1175
1176
1177
1178
1158
1159
1160
1161
1162
1163
1164


1165
1166
1167


1168
1169
1170
1171
1172
1173
1174
1175
1176







-
-
+
+

-
-
+
+







		return TCL_ERROR;
	    }

	    if (Tcl_GetIntFromObj(interp, objv[5], &y) != TCL_OK) {
		return TCL_ERROR;
	    }

	    pwPtr->slaves[sash]->markx = x;
	    pwPtr->slaves[sash]->marky = y;
	    pwPtr->panes[sash]->markx = x;
	    pwPtr->panes[sash]->marky = y;
	} else {
	    coords[0] = Tcl_NewWideIntObj(pwPtr->slaves[sash]->markx);
	    coords[1] = Tcl_NewWideIntObj(pwPtr->slaves[sash]->marky);
	    coords[0] = Tcl_NewWideIntObj(pwPtr->panes[sash]->markx);
	    coords[1] = Tcl_NewWideIntObj(pwPtr->panes[sash]->marky);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(2, coords));
	}
	break;

    case SASH_DRAGTO:
    case SASH_PLACE:
	if (objc != 6) {
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
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







-
+


-
+

-
+



-
+

-
+







	    return TCL_ERROR;
	}

	if (Tcl_GetIntFromObj(interp, objv[5], &y) != TCL_OK) {
	    return TCL_ERROR;
	}

	slavePtr = pwPtr->slaves[sash];
	panePtr = pwPtr->panes[sash];
	if (pwPtr->orient == ORIENT_HORIZONTAL) {
	    if (index == SASH_PLACE) {
		diff = x - pwPtr->slaves[sash]->sashx;
		diff = x - pwPtr->panes[sash]->sashx;
	    } else {
		diff = x - pwPtr->slaves[sash]->markx;
		diff = x - pwPtr->panes[sash]->markx;
	    }
	} else {
	    if (index == SASH_PLACE) {
		diff = y - pwPtr->slaves[sash]->sashy;
		diff = y - pwPtr->panes[sash]->sashy;
	    } else {
		diff = y - pwPtr->slaves[sash]->marky;
		diff = y - pwPtr->panes[sash]->marky;
	    }
	}

	MoveSash(pwPtr, sash, diff);
	ComputeGeometry(pwPtr);
    }
    return TCL_OK;
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375



1376
1377
1378
1379
1380
1381



1382
1383
1384
1385
1386
1387
1388
1364
1365
1366
1367
1368
1369
1370



1371
1372
1373
1374
1375
1376



1377
1378
1379
1380
1381
1382
1383
1384
1385
1386







-
-
-
+
+
+



-
-
-
+
+
+







	if (pwPtr->tkwin != NULL && !(pwPtr->flags & REDRAW_PENDING)) {
	    Tcl_DoWhenIdle(DisplayPanedWindow, pwPtr);
	    pwPtr->flags |= REDRAW_PENDING;
	}
    } else if (eventPtr->type == DestroyNotify) {
	DestroyPanedWindow(pwPtr);
    } else if (eventPtr->type == UnmapNotify) {
        for (i = 0; i < pwPtr->numSlaves; i++) {
            if (!pwPtr->slaves[i]->hide) {
                Tk_UnmapWindow(pwPtr->slaves[i]->tkwin);
        for (i = 0; i < pwPtr->numPanes; i++) {
            if (!pwPtr->panes[i]->hide) {
                Tk_UnmapWindow(pwPtr->panes[i]->tkwin);
            }
        }
    } else if (eventPtr->type == MapNotify) {
        for (i = 0; i < pwPtr->numSlaves; i++) {
            if (!pwPtr->slaves[i]->hide) {
                Tk_MapWindow(pwPtr->slaves[i]->tkwin);
        for (i = 0; i < pwPtr->numPanes; i++) {
            if (!pwPtr->panes[i]->hide) {
                Tk_MapWindow(pwPtr->panes[i]->tkwin);
            }
        }
    }
}

/*
 *----------------------------------------------------------------------
1440
1441
1442
1443
1444
1445
1446
1447

1448
1449
1450
1451
1452
1453
1454
1438
1439
1440
1441
1442
1443
1444

1445
1446
1447
1448
1449
1450
1451
1452







-
+







 */

static void
DisplayPanedWindow(
    ClientData clientData)	/* Information about window. */
{
    PanedWindow *pwPtr = (PanedWindow *)clientData;
    Slave *slavePtr;
    Pane *panePtr;
    Pixmap pixmap;
    Tk_Window tkwin = pwPtr->tkwin;
    int i, sashWidth, sashHeight;
    const int horizontal = (pwPtr->orient == ORIENT_HORIZONTAL);
    int first, last;

    pwPtr->flags &= ~REDRAW_PENDING;
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
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







-
-
-
+
+
+




-
+




-
+







    }

    /*
     * Draw the sashes.
     */

    GetFirstLastVisiblePane(pwPtr, &first, &last);
    for (i = 0; i < pwPtr->numSlaves - 1; i++) {
	slavePtr = pwPtr->slaves[i];
	if (slavePtr->hide || i == last) {
    for (i = 0; i < pwPtr->numPanes - 1; i++) {
	panePtr = pwPtr->panes[i];
	if (panePtr->hide || i == last) {
	    continue;
	}
	if (sashWidth > 0 && sashHeight > 0) {
	    Tk_Fill3DRectangle(tkwin, pixmap, pwPtr->background,
		    slavePtr->sashx, slavePtr->sashy, sashWidth, sashHeight,
		    panePtr->sashx, panePtr->sashy, sashWidth, sashHeight,
		    1, pwPtr->sashRelief);
	}
	if (pwPtr->showHandle) {
	    Tk_Fill3DRectangle(tkwin, pixmap, pwPtr->background,
		    slavePtr->handlex, slavePtr->handley,
		    panePtr->handlex, panePtr->handley,
		    pwPtr->handleSize, pwPtr->handleSize, 1,
		    TK_RELIEF_RAISED);
	}
    }

#ifndef TK_NO_DOUBLE_BUFFERING
    /*
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
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







-
-
-
-
+
+
+
+


-
-
-
-
-
+
+
+
+
+

-
-
+
+

-
-
+
+







	Tcl_CancelIdleCall(DisplayPanedWindow, pwPtr);
    }
    if (pwPtr->flags & RESIZE_PENDING) {
	Tcl_CancelIdleCall(ArrangePanes, pwPtr);
    }

    /*
     * Clean up the slave list; foreach slave:
     *  o  Cancel the slave's structure notification callback
     *  o  Cancel geometry management for the slave.
     *  o  Free memory for the slave
     * Clean up the pane list; foreach pane:
     *  o  Cancel the pane's structure notification callback
     *  o  Cancel geometry management for the pane.
     *  o  Free memory for the pane
     */

    for (i = 0; i < pwPtr->numSlaves; i++) {
	Tk_DeleteEventHandler(pwPtr->slaves[i]->tkwin, StructureNotifyMask,
		SlaveStructureProc, pwPtr->slaves[i]);
	Tk_ManageGeometry(pwPtr->slaves[i]->tkwin, NULL, NULL);
	Tk_FreeConfigOptions((char *) pwPtr->slaves[i], pwPtr->slaveOpts,
    for (i = 0; i < pwPtr->numPanes; i++) {
	Tk_DeleteEventHandler(pwPtr->panes[i]->tkwin, StructureNotifyMask,
		PaneStructureProc, pwPtr->panes[i]);
	Tk_ManageGeometry(pwPtr->panes[i]->tkwin, NULL, NULL);
	Tk_FreeConfigOptions((char *) pwPtr->panes[i], pwPtr->paneOpts,
		pwPtr->tkwin);
	ckfree(pwPtr->slaves[i]);
	pwPtr->slaves[i] = NULL;
	ckfree(pwPtr->panes[i]);
	pwPtr->panes[i] = NULL;
    }
    if (pwPtr->slaves) {
	ckfree(pwPtr->slaves);
    if (pwPtr->panes) {
	ckfree(pwPtr->panes);
    }

    /*
     * Remove the widget command from the interpreter.
     */

    Tcl_DeleteCommandFromToken(pwPtr->interp, pwPtr->widgetCmd);
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
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







-
+


-
-
+
+
-







-
+

-
-
+
+

-
-
+
+








-
+


-
+





-
+






-
-
+
+

-
+

-
-
+
+
-

-
-
+
+

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

















-
+






-
+



-
-
+
+














-
+





-
+







 *--------------------------------------------------------------
 */

static void
PanedWindowReqProc(
    ClientData clientData,	/* Paned window's information about window
				 * that got new preferred geometry. */
    Tk_Window tkwin)		/* Other Tk-related information about the
    TCL_UNUSED(Tk_Window))		/* Other Tk-related information about the
				 * window. */
{
    Slave *slavePtr = (Slave *)clientData;
    PanedWindow *pwPtr = (PanedWindow *) slavePtr->masterPtr;
    Pane *panePtr = (Pane *)clientData;
    PanedWindow *pwPtr = (PanedWindow *) panePtr->containerPtr;
    (void)tkwin;

    if (Tk_IsMapped(pwPtr->tkwin)) {
	if (!(pwPtr->flags & RESIZE_PENDING)) {
	    pwPtr->flags |= RESIZE_PENDING;
	    Tcl_DoWhenIdle(ArrangePanes, pwPtr);
	}
    } else {
	int doubleBw = 2 * Tk_Changes(slavePtr->tkwin)->border_width;
	int doubleBw = 2 * Tk_Changes(panePtr->tkwin)->border_width;

	if (slavePtr->width <= 0) {
	    slavePtr->paneWidth = Tk_ReqWidth(slavePtr->tkwin) + doubleBw;
	if (panePtr->width <= 0) {
	    panePtr->paneWidth = Tk_ReqWidth(panePtr->tkwin) + doubleBw;
	}
	if (slavePtr->height <= 0) {
	    slavePtr->paneHeight = Tk_ReqHeight(slavePtr->tkwin) + doubleBw;
	if (panePtr->height <= 0) {
	    panePtr->paneHeight = Tk_ReqHeight(panePtr->tkwin) + doubleBw;
	}
	ComputeGeometry(pwPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * PanedWindowLostSlaveProc --
 * PanedWindowLostPaneProc --
 *
 *	This function is invoked by Tk whenever some other geometry claims
 *	control over a slave that used to be managed by us.
 *	control over a pane that used to be managed by us.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Forgets all information about the slave. Causes geometry to be
 *	Forgets all information about the pane. Causes geometry to be
 *	recomputed for the panedwindow.
 *
 *--------------------------------------------------------------
 */

static void
PanedWindowLostSlaveProc(
    ClientData clientData,	/* Grid structure for slave window that was
PanedWindowLostPaneProc(
    ClientData clientData,	/* Grid structure for the pane that was
				 * stolen away. */
    Tk_Window tkwin)		/* Tk's handle for the slave window. */
    TCL_UNUSED(Tk_Window))		/* Tk's handle for the pane. */
{
    Slave *slavePtr = (Slave *)clientData;
    PanedWindow *pwPtr = (PanedWindow *) slavePtr->masterPtr;
    Pane *panePtr = (Pane *)clientData;
    PanedWindow *pwPtr = (PanedWindow *) panePtr->containerPtr;
    (void)tkwin;

    if (pwPtr->tkwin != Tk_Parent(slavePtr->tkwin)) {
	Tk_UnmaintainGeometry(slavePtr->tkwin, pwPtr->tkwin);
    if (pwPtr->tkwin != Tk_Parent(panePtr->tkwin)) {
	Tk_UnmaintainGeometry(panePtr->tkwin, pwPtr->tkwin);
    }
    Unlink(slavePtr);
    Tk_DeleteEventHandler(slavePtr->tkwin, StructureNotifyMask,
	    SlaveStructureProc, slavePtr);
    Tk_UnmapWindow(slavePtr->tkwin);
    slavePtr->tkwin = NULL;
    ckfree(slavePtr);
    Unlink(panePtr);
    Tk_DeleteEventHandler(panePtr->tkwin, StructureNotifyMask,
	    PaneStructureProc, panePtr);
    Tk_UnmapWindow(panePtr->tkwin);
    panePtr->tkwin = NULL;
    ckfree(panePtr);
    ComputeGeometry(pwPtr);
}

/*
 *--------------------------------------------------------------
 *
 * ArrangePanes --
 *
 *	This function is invoked (using the Tcl_DoWhenIdle mechanism) to
 *	re-layout a set of windows managed by a paned window. It is invoked at
 *	idle time so that a series of pane requests can be merged into a
 *	single layout operation.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The slaves of masterPtr may get resized or moved.
 *	The panes of containerPtr may get resized or moved.
 *
 *--------------------------------------------------------------
 */

static void
ArrangePanes(
    ClientData clientData)	/* Structure describing parent whose slaves
    ClientData clientData)	/* Structure describing parent whose panes
				 * are to be re-layed out. */
{
    PanedWindow *pwPtr = (PanedWindow *)clientData;
    Slave *slavePtr;
    int i, slaveWidth, slaveHeight, slaveX, slaveY;
    Pane *panePtr;
    int i, newPaneWidth, newPaneHeight, paneX, paneY;
    int paneWidth, paneHeight, paneSize, paneMinSize;
    int doubleBw;
    int x, y;
    int sashWidth, sashOffset, sashCount, handleOffset;
    int sashReserve, sxReserve, syReserve;
    int internalBW;
    int paneDynSize, paneDynMinSize, pwHeight, pwWidth, pwSize;
    int first, last;
    int stretchReserve, stretchAmount;
    const int horizontal = (pwPtr->orient == ORIENT_HORIZONTAL);

    pwPtr->flags &= ~(REQUESTED_RELAYOUT|RESIZE_PENDING);

    /*
     * If the parent has no slaves anymore, then don't do anything at all:
     * If the parent has no panes anymore, then don't do anything at all:
     * just leave the parent's size as-is. Otherwise there is no way to
     * "relinquish" control over the parent so another geometry manager can
     * take over.
     */

    if (pwPtr->numSlaves == 0) {
    if (pwPtr->numPanes == 0) {
	return;
    }

    Tcl_Preserve(pwPtr);

    /*
     * Find index of first and last visible panes.
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
1771
1772
1773
1774
1775
1776
1777


1778
1779
1780

1781
1782
1783
1784
1785

1786
1787
1788
1789
1790


1791
1792
1793

1794
1795

1796
1797


1798
1799
1800

1801
1802

1803
1804

1805
1806
1807

1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819


1820
1821
1822



1823
1824
1825
1826
1827
1828
1829

1830
1831
1832
1833

1834
1835
1836
1837
1838
1839






1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851


1852
1853
1854

1855
1856
1857
1858


1859
1860
1861

1862
1863
1864
1865

1866
1867
1868
1869
1870
1871
1872
1873
1874
1875

1876
1877
1878
1879
1880
1881
1882
1883







-
-
+
+

-
+




-
+




-
-
+
+

-
+

-
+

-
-
+
+

-
+

-
+

-
+


-
+











-
-
+
+

-
-
-
+
+
+




-
+



-
+





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






-
-
+
+

-
+



-
-
+
+

-
+



-
+









-
+







		+ pwPtr->sashPad;
    } else {
	sashWidth = (2 * pwPtr->sashPad) + pwPtr->sashWidth;
	handleOffset = ((pwPtr->sashWidth - pwPtr->handleSize) / 2)
		+ pwPtr->sashPad;
    }

    for (i = sashCount = 0; i < pwPtr->numSlaves; i++) {
	slavePtr = pwPtr->slaves[i];
    for (i = sashCount = 0; i < pwPtr->numPanes; i++) {
	panePtr = pwPtr->panes[i];

	if (slavePtr->hide) {
	if (panePtr->hide) {
	    continue;
	}

	/*
	 * Compute the total size needed by all the slaves and the left-over,
	 * Compute the total size needed by all the panes and the left-over,
	 * or shortage of space available.
	 */

	if (horizontal) {
            if (slavePtr->width > 0) {
                paneSize = slavePtr->width;
            if (panePtr->width > 0) {
                paneSize = panePtr->width;
            } else {
                paneSize = slavePtr->paneWidth;
                paneSize = panePtr->paneWidth;
            }
	    stretchReserve -= paneSize + (2 * slavePtr->padx);
	    stretchReserve -= paneSize + (2 * panePtr->padx);
	} else {
            if (slavePtr->height > 0) {
                paneSize = slavePtr->height;
            if (panePtr->height > 0) {
                paneSize = panePtr->height;
            } else {
                paneSize = slavePtr->paneHeight;
                paneSize = panePtr->paneHeight;
            }
	    stretchReserve -= paneSize + (2 * slavePtr->pady);
	    stretchReserve -= paneSize + (2 * panePtr->pady);
	}
	if (IsStretchable(slavePtr->stretch,i,first,last)
	if (IsStretchable(panePtr->stretch,i,first,last)
		&& Tk_IsMapped(pwPtr->tkwin)) {
	    paneDynSize += paneSize;
	    paneDynMinSize += slavePtr->minSize;
	    paneDynMinSize += panePtr->minSize;
	}
	if (i != last) {
	    stretchReserve -= sashWidth;
	    sashCount++;
	}
    }

    /*
     * Second pass; adjust/arrange panes.
     */

    for (i = 0; i < pwPtr->numSlaves; i++) {
	slavePtr = pwPtr->slaves[i];
    for (i = 0; i < pwPtr->numPanes; i++) {
	panePtr = pwPtr->panes[i];

	if (slavePtr->hide) {
	    Tk_UnmaintainGeometry(slavePtr->tkwin, pwPtr->tkwin);
	    Tk_UnmapWindow(slavePtr->tkwin);
	if (panePtr->hide) {
	    Tk_UnmaintainGeometry(panePtr->tkwin, pwPtr->tkwin);
	    Tk_UnmapWindow(panePtr->tkwin);
	    continue;
	}

	/*
	 * Compute the size of this slave. The algorithm (assuming a
	 * Compute the size of this pane. The algorithm (assuming a
	 * horizontal paned window) is:
	 *
	 * 1.  Get "base" dimensions. If a width or height is specified for
	 *     this slave, use those values; else use the ReqWidth/ReqHeight.
	 *     this pane, use those values; else use the ReqWidth/ReqHeight.
	 * 2.  Using base dimensions, pane dimensions, and sticky values,
	 *     determine the x and y, and actual width and height of the
	 *     widget.
	 */

	doubleBw = 2 * Tk_Changes(slavePtr->tkwin)->border_width;
	slaveWidth = (slavePtr->width > 0 ? slavePtr->width :
		Tk_ReqWidth(slavePtr->tkwin) + doubleBw);
	slaveHeight = (slavePtr->height > 0 ? slavePtr->height :
		Tk_ReqHeight(slavePtr->tkwin) + doubleBw);
	paneMinSize = slavePtr->minSize;
	doubleBw = 2 * Tk_Changes(panePtr->tkwin)->border_width;
	newPaneWidth = (panePtr->width > 0 ? panePtr->width :
		Tk_ReqWidth(panePtr->tkwin) + doubleBw);
	newPaneHeight = (panePtr->height > 0 ? panePtr->height :
		Tk_ReqHeight(panePtr->tkwin) + doubleBw);
	paneMinSize = panePtr->minSize;

	/*
	 * Calculate pane width and height.
	 */

	if (horizontal) {
            if (slavePtr->width > 0) {
                paneSize = slavePtr->width;
            if (panePtr->width > 0) {
                paneSize = panePtr->width;
            } else {
                paneSize = slavePtr->paneWidth;
                paneSize = panePtr->paneWidth;
            }
	    pwSize = pwWidth;
	} else {
            if (slavePtr->height > 0) {
                paneSize = slavePtr->height;
            if (panePtr->height > 0) {
                paneSize = panePtr->height;
            } else {
                paneSize = slavePtr->paneHeight;
                paneSize = panePtr->paneHeight;
            }
	    pwSize = pwHeight;
	}
	if (IsStretchable(slavePtr->stretch, i, first, last)) {
	if (IsStretchable(panePtr->stretch, i, first, last)) {
	    double frac;

	    if (paneDynSize > 0) {
		frac = (double)paneSize / (double)paneDynSize;
	    } else {
		frac = (double)paneSize / (double)pwSize;
	    }

	    paneDynSize -= paneSize;
	    paneDynMinSize -= slavePtr->minSize;
	    paneDynMinSize -= panePtr->minSize;
	    stretchAmount = (int) (frac * stretchReserve);
	    if (paneSize + stretchAmount >= paneMinSize) {
		stretchReserve -= stretchAmount;
		paneSize += stretchAmount;
	    } else {
		stretchReserve += paneSize - paneMinSize;
		paneSize = paneMinSize;
1898
1899
1900
1901
1902
1903
1904
1905

1906
1907

1908
1909
1910
1911
1912
1913
1914
1894
1895
1896
1897
1898
1899
1900

1901
1902

1903
1904
1905
1906
1907
1908
1909
1910







-
+

-
+







	    } else {
		paneSize += paneDynSize - paneDynMinSize + stretchReserve;
		stretchReserve = paneDynMinSize - paneDynSize;
	    }
	}
	if (horizontal) {
	    paneWidth = paneSize;
	    paneHeight = pwHeight - (2 * slavePtr->pady);
	    paneHeight = pwHeight - (2 * panePtr->pady);
	} else {
	    paneWidth = pwWidth - (2 * slavePtr->padx);
	    paneWidth = pwWidth - (2 * panePtr->padx);
	    paneHeight = paneSize;
	}

	/*
	 * Adjust for area reserved for sashes.
	 */

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
1924
1925
1926
1927
1928
1929
1930


1931
1932
1933


1934
1935
1936
1937


1938
1939
1940
1941
1942
1943
1944
1945
1946

1947
1948
1949
1950




1951
1952
1953
1954
1955
1956

1957
1958
1959
1960




1961
1962
1963
1964
1965
1966
1967
1968

1969
1970
1971




1972
1973
1974
1975
1976


1977
1978
1979
1980
1981
1982
1983





1984
1985
1986
1987
1988
1989


1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002

2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015

2016
2017

2018
2019
2020


2021
2022
2023
2024
2025
2026

2027
2028
2029
2030




2031
2032
2033
2034
2035
2036
2037
2038
2039
2040

2041
2042
2043



2044
2045
2046
2047


2048
2049
2050
2051
2052




2053
2054
2055
2056
2057
2058
2059

2060
2061
2062
2063

2064
2065

2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077

2078
2079
2080
2081
2082
2083
2084
2085
2086

2087
2088
2089
2090
2091
2092
2093



2094
2095
2096
2097
2098
2099
2100
2101
2102
2103







-
-
+
+

-
-
+
+


-
-
+
+







-
+



-
-
-
-
+
+
+
+


-
+



-
-
-
-
+
+
+
+




-
+


-
-
-
-
+
+
+
+

-
-
+
+





-
-
-
-
-
+
+
+
+
+

-
-
+
+











-
+












-
+

-
+


-
-
+
+




-
+



-
-
-
-
+
+
+
+






-
+


-
-
-
+
+
+

-
-
+
+



-
-
-
-
+
+
+
+



-
+



-
+

-
+











-
+








-
+






-
-
-
+
+
+







	if (pwWidth - sxReserve < x + paneWidth - internalBW) {
	    paneWidth = pwWidth - sxReserve - x + internalBW;
	}
	if (pwHeight - syReserve < y + paneHeight - internalBW) {
	    paneHeight = pwHeight - syReserve - y + internalBW;
	}

	if (slaveWidth > paneWidth) {
	    slaveWidth = paneWidth;
	if (newPaneWidth > paneWidth) {
	    newPaneWidth = paneWidth;
	}
	if (slaveHeight > paneHeight) {
	    slaveHeight = paneHeight;
	if (newPaneHeight > paneHeight) {
	    newPaneHeight = paneHeight;
	}

	slavePtr->x = x;
	slavePtr->y = y;
	panePtr->x = x;
	panePtr->y = y;

	/*
	 * Compute the location of the sash at the right or bottom of the
	 * parcel and the location of the next parcel.
	 */

	if (horizontal) {
	    x += paneWidth + (2 * slavePtr->padx);
	    x += paneWidth + (2 * panePtr->padx);
	    if (x < internalBW) {
		x = internalBW;
	    }
	    slavePtr->sashx = x + sashOffset;
	    slavePtr->sashy = y;
	    slavePtr->handlex = x + handleOffset;
	    slavePtr->handley = y + pwPtr->handlePad;
	    panePtr->sashx = x + sashOffset;
	    panePtr->sashy = y;
	    panePtr->handlex = x + handleOffset;
	    panePtr->handley = y + pwPtr->handlePad;
	    x += sashWidth;
	} else {
	    y += paneHeight + (2 * slavePtr->pady);
	    y += paneHeight + (2 * panePtr->pady);
	    if (y < internalBW) {
		y = internalBW;
	    }
	    slavePtr->sashx = x;
	    slavePtr->sashy = y + sashOffset;
	    slavePtr->handlex = x + pwPtr->handlePad;
	    slavePtr->handley = y + handleOffset;
	    panePtr->sashx = x;
	    panePtr->sashy = y + sashOffset;
	    panePtr->handlex = x + pwPtr->handlePad;
	    panePtr->handley = y + handleOffset;
	    y += sashWidth;
	}

	/*
	 * Compute the actual dimensions of the slave in the pane.
	 * Compute the actual dimensions of the pane in the pane.
	 */

	slaveX = slavePtr->x;
	slaveY = slavePtr->y;
	AdjustForSticky(slavePtr->sticky, paneWidth, paneHeight,
		&slaveX, &slaveY, &slaveWidth, &slaveHeight);
	paneX = panePtr->x;
	paneY = panePtr->y;
	AdjustForSticky(panePtr->sticky, paneWidth, paneHeight,
		&paneX, &paneY, &newPaneWidth, &newPaneHeight);

	slaveX += slavePtr->padx;
	slaveY += slavePtr->pady;
	paneX += panePtr->padx;
	paneY += panePtr->pady;

	/*
	 * Now put the window in the proper spot.
	 */

	if (slaveWidth <= 0 || slaveHeight <= 0 ||
		(horizontal ? slaveX - internalBW > pwWidth :
		slaveY - internalBW > pwHeight)) {
	    Tk_UnmaintainGeometry(slavePtr->tkwin, pwPtr->tkwin);
	    Tk_UnmapWindow(slavePtr->tkwin);
	if (newPaneWidth <= 0 || newPaneHeight <= 0 ||
		(horizontal ? paneX - internalBW > pwWidth :
		paneY - internalBW > pwHeight)) {
	    Tk_UnmaintainGeometry(panePtr->tkwin, pwPtr->tkwin);
	    Tk_UnmapWindow(panePtr->tkwin);
	} else {
	    Tk_MaintainGeometry(slavePtr->tkwin, pwPtr->tkwin,
		    slaveX, slaveY, slaveWidth, slaveHeight);
	    Tk_MaintainGeometry(panePtr->tkwin, pwPtr->tkwin,
		    paneX, paneY, newPaneWidth, newPaneHeight);
	}
	sashCount--;
    }
    Tcl_Release(pwPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Unlink --
 *
 *	Remove a slave from a paned window.
 *	Remove a pane from a paned window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The paned window will be scheduled for re-arranging and redrawing.
 *
 *----------------------------------------------------------------------
 */

static void
Unlink(
    Slave *slavePtr)		/* Window to unlink. */
    Pane *panePtr)		/* Window to unlink. */
{
    PanedWindow *masterPtr;
    PanedWindow *containerPtr;
    int i, j;

    masterPtr = slavePtr->masterPtr;
    if (masterPtr == NULL) {
    containerPtr = panePtr->containerPtr;
    if (containerPtr == NULL) {
	return;
    }

    /*
     * Find the specified slave in the panedwindow's list of slaves, then
     * Find the specified pane in the panedwindow's list of panes, then
     * remove it from that list.
     */

    for (i = 0; i < masterPtr->numSlaves; i++) {
	if (masterPtr->slaves[i] == slavePtr) {
	    for (j = i; j < masterPtr->numSlaves - 1; j++) {
		masterPtr->slaves[j] = masterPtr->slaves[j + 1];
    for (i = 0; i < containerPtr->numPanes; i++) {
	if (containerPtr->panes[i] == panePtr) {
	    for (j = i; j < containerPtr->numPanes - 1; j++) {
		containerPtr->panes[j] = containerPtr->panes[j + 1];
	    }
	    break;
	}
    }

    /*
     * Clean out any -after or -before references to this slave
     * Clean out any -after or -before references to this pane
     */

    for (i = 0; i < masterPtr->numSlaves; i++) {
	if (masterPtr->slaves[i]->before == slavePtr->tkwin) {
	    masterPtr->slaves[i]->before = NULL;
    for (i = 0; i < containerPtr->numPanes; i++) {
	if (containerPtr->panes[i]->before == panePtr->tkwin) {
	    containerPtr->panes[i]->before = NULL;
	}
	if (masterPtr->slaves[i]->after == slavePtr->tkwin) {
	    masterPtr->slaves[i]->after = NULL;
	if (containerPtr->panes[i]->after == panePtr->tkwin) {
	    containerPtr->panes[i]->after = NULL;
	}
    }

    masterPtr->flags |= REQUESTED_RELAYOUT;
    if (!(masterPtr->flags & REDRAW_PENDING)) {
	masterPtr->flags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(DisplayPanedWindow, masterPtr);
    containerPtr->flags |= REQUESTED_RELAYOUT;
    if (!(containerPtr->flags & REDRAW_PENDING)) {
	containerPtr->flags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(DisplayPanedWindow, containerPtr);
    }

    /*
     * Set the slave's masterPtr to NULL, so that we can tell that the slave
     * Set the pane's containerPtr to NULL, so that we can tell that the pane
     * is no longer attached to any panedwindow.
     */

    slavePtr->masterPtr = NULL;
    panePtr->containerPtr = NULL;

    masterPtr->numSlaves--;
    containerPtr->numPanes--;
}

/*
 *----------------------------------------------------------------------
 *
 * GetPane --
 *
 *	Given a token to a Tk window, find the pane that corresponds to that
 *	token in a given paned window.
 *
 * Results:
 *	Pointer to the slave structure, or NULL if the window is not managed
 *	Pointer to the pane structure, or NULL if the window is not managed
 *	by this paned window.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Slave *
static Pane *
GetPane(
    PanedWindow *pwPtr,		/* Pointer to the paned window info. */
    Tk_Window tkwin)		/* Window to search for. */
{
    int i;

    for (i = 0; i < pwPtr->numSlaves; i++) {
	if (pwPtr->slaves[i]->tkwin == tkwin) {
	    return pwPtr->slaves[i];
    for (i = 0; i < pwPtr->numPanes; i++) {
	if (pwPtr->panes[i]->tkwin == tkwin) {
	    return pwPtr->panes[i];
	}
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
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
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







-
-
+
+











-
+









-
-
+
+






-
+



-
-
+
+


-
-
-
+
+
+










-
+

















-
+







GetFirstLastVisiblePane(
    PanedWindow *pwPtr,		/* Pointer to the paned window info. */
    int *firstPtr, 		/* Returned index for first. */
    int *lastPtr)  		/* Returned index for last. */
{
    int i;

    for (i = 0, *lastPtr = 0, *firstPtr = -1; i < pwPtr->numSlaves; i++) {
	if (pwPtr->slaves[i]->hide == 0) {
    for (i = 0, *lastPtr = 0, *firstPtr = -1; i < pwPtr->numPanes; i++) {
	if (pwPtr->panes[i]->hide == 0) {
	    if (*firstPtr < 0) {
		*firstPtr = i;
	    }
	    *lastPtr = i;
	}
    }
}

/*
 *--------------------------------------------------------------
 *
 * SlaveStructureProc --
 * PaneStructureProc --
 *
 *	This function is invoked whenever StructureNotify events occur for a
 *	window that's managed by a paned window. This function's only purpose
 *	is to clean up when windows are deleted.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The paned window slave structure associated with the window
 *	is freed, and the slave is disassociated from the paned
 *	The paned window pane structure associated with the window
 *	is freed, and the pane is disassociated from the paned
 *	window which managed it.
 *
 *--------------------------------------------------------------
 */

static void
SlaveStructureProc(
PaneStructureProc(
    ClientData clientData,	/* Pointer to record describing window item. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    Slave *slavePtr = (Slave *)clientData;
    PanedWindow *pwPtr = slavePtr->masterPtr;
    Pane *panePtr = (Pane *)clientData;
    PanedWindow *pwPtr = panePtr->containerPtr;

    if (eventPtr->type == DestroyNotify) {
	Unlink(slavePtr);
	slavePtr->tkwin = NULL;
	ckfree(slavePtr);
	Unlink(panePtr);
	panePtr->tkwin = NULL;
	ckfree(panePtr);
	ComputeGeometry(pwPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ComputeGeometry --
 *
 *	Compute geometry for the paned window, including coordinates of all
 *	slave windows and each sash.
 *	panes and each sash.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Recomputes geometry information for a paned window.
 *
 *----------------------------------------------------------------------
 */

static void
ComputeGeometry(
    PanedWindow *pwPtr)		/* Pointer to the Paned Window structure. */
{
    int i, x, y, doubleBw, internalBw;
    int sashWidth, sashOffset, handleOffset;
    int reqWidth, reqHeight, dim;
    Slave *slavePtr;
    Pane *panePtr;
    const int horizontal = (pwPtr->orient == ORIENT_HORIZONTAL);

    pwPtr->flags |= REQUESTED_RELAYOUT;

    x = y = internalBw = Tk_InternalBorderLeft(pwPtr->tkwin);
    reqWidth = reqHeight = 0;

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







-
-
+
+

-
+




-
+



-
-
+
+








-
-
+
+


-
-
+
+









-
-
-
-
-
+
+
+
+
+


-
-
-
-
-
+
+
+
+
+




-
+





-
-
+
+


-
-
+
+

-
-
+
+

-
+





-
-
+
+


-
-
+
+

-
-
+
+

-
+

















-
+







		+ pwPtr->sashPad;
    } else {
	sashWidth = (2 * pwPtr->sashPad) + pwPtr->sashWidth;
	handleOffset = ((pwPtr->sashWidth - pwPtr->handleSize) / 2)
		+ pwPtr->sashPad;
    }

    for (i = 0; i < pwPtr->numSlaves; i++) {
	slavePtr = pwPtr->slaves[i];
    for (i = 0; i < pwPtr->numPanes; i++) {
	panePtr = pwPtr->panes[i];

	if (slavePtr->hide) {
	if (panePtr->hide) {
	    continue;
	}

	/*
	 * First set the coordinates for the top left corner of the slave's
	 * First set the coordinates for the top left corner of the pane's
	 * parcel.
	 */

	slavePtr->x = x;
	slavePtr->y = y;
	panePtr->x = x;
	panePtr->y = y;

	/*
	 * Make sure the pane's paned dimension is at least minsize. This
	 * check may be redundant, since the only way to change a pane's size
	 * is by moving a sash, and that code checks the minsize.
	 */

	if (horizontal) {
	    if (slavePtr->paneWidth < slavePtr->minSize) {
		slavePtr->paneWidth = slavePtr->minSize;
	    if (panePtr->paneWidth < panePtr->minSize) {
		panePtr->paneWidth = panePtr->minSize;
	    }
	} else {
	    if (slavePtr->paneHeight < slavePtr->minSize) {
		slavePtr->paneHeight = slavePtr->minSize;
	    if (panePtr->paneHeight < panePtr->minSize) {
		panePtr->paneHeight = panePtr->minSize;
	    }
	}

	/*
	 * Compute the location of the sash at the right or bottom of the
	 * parcel.
	 */

	if (horizontal) {
	    x += slavePtr->paneWidth + (2 * slavePtr->padx);
	    slavePtr->sashx = x + sashOffset;
	    slavePtr->sashy = y;
	    slavePtr->handlex = x + handleOffset;
	    slavePtr->handley = y + pwPtr->handlePad;
	    x += panePtr->paneWidth + (2 * panePtr->padx);
	    panePtr->sashx = x + sashOffset;
	    panePtr->sashy = y;
	    panePtr->handlex = x + handleOffset;
	    panePtr->handley = y + pwPtr->handlePad;
	    x += sashWidth;
	} else {
	    y += slavePtr->paneHeight + (2 * slavePtr->pady);
	    slavePtr->sashx = x;
	    slavePtr->sashy = y + sashOffset;
	    slavePtr->handlex = x + pwPtr->handlePad;
	    slavePtr->handley = y + handleOffset;
	    y += panePtr->paneHeight + (2 * panePtr->pady);
	    panePtr->sashx = x;
	    panePtr->sashy = y + sashOffset;
	    panePtr->handlex = x + pwPtr->handlePad;
	    panePtr->handley = y + handleOffset;
	    y += sashWidth;
	}

	/*
	 * Find the maximum height/width of the slaves, for computing the
	 * Find the maximum height/width of the panes, for computing the
	 * requested height/width of the paned window.
	 */

	if (horizontal) {
	    /*
	     * If the slave has an explicit height set, use that; otherwise,
	     * use the slave's requested height.
	     * If the pane has an explicit height set, use that; otherwise,
	     * use the pane's requested height.
	     */

	    if (slavePtr->height > 0) {
		dim = slavePtr->height;
	    if (panePtr->height > 0) {
		dim = panePtr->height;
	    } else {
		doubleBw = 2 * Tk_Changes(slavePtr->tkwin)->border_width;
		dim = Tk_ReqHeight(slavePtr->tkwin) + doubleBw;
		doubleBw = 2 * Tk_Changes(panePtr->tkwin)->border_width;
		dim = Tk_ReqHeight(panePtr->tkwin) + doubleBw;
	    }
	    dim += 2 * slavePtr->pady;
	    dim += 2 * panePtr->pady;
	    if (dim > reqHeight) {
		reqHeight = dim;
	    }
	} else {
	    /*
	     * If the slave has an explicit width set use that; otherwise, use
	     * the slave's requested width.
	     * If the pane has an explicit width set use that; otherwise, use
	     * the pane's requested width.
	     */

	    if (slavePtr->width > 0) {
		dim = slavePtr->width;
	    if (panePtr->width > 0) {
		dim = panePtr->width;
	    } else {
		doubleBw = 2 * Tk_Changes(slavePtr->tkwin)->border_width;
		dim = Tk_ReqWidth(slavePtr->tkwin) + doubleBw;
		doubleBw = 2 * Tk_Changes(panePtr->tkwin)->border_width;
		dim = Tk_ReqWidth(panePtr->tkwin) + doubleBw;
	    }
	    dim += 2 * slavePtr->padx;
	    dim += 2 * panePtr->padx;
	    if (dim > reqWidth) {
		reqWidth = dim;
	    }
	}
    }

    /*
     * The loop above should have left x (or y) equal to the sum of the widths
     * (or heights) of the widgets, plus the size of one sash and the sash
     * padding for each widget, plus the width of the left (or top) border of
     * the paned window.
     *
     * The requested width (or height) is therefore x (or y) minus the size of
     * one sash and padding, plus the width of the right (or bottom) border of
     * the paned window.
     *
     * The height (or width) is equal to the maximum height (or width) of the
     * slaves, plus the width of the border of the top and bottom (or left and
     * panes, plus the width of the border of the top and bottom (or left and
     * right) of the paned window.
     *
     * If the panedwindow has an explicit width/height set use that;
     * otherwise, use the requested width/height.
     */

    if (horizontal) {
2369
2370
2371
2372
2373
2374
2375
2376

2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2365
2366
2367
2368
2369
2370
2371

2372
2373


2374
2375
2376
2377
2378
2379
2380







-
+

-
-







 *
 *----------------------------------------------------------------------
 */

static void
DestroyOptionTables(
    ClientData clientData,	/* Pointer to the OptionTables struct */
    Tcl_Interp *dummy)		/* Pointer to the calling interp */
    TCL_UNUSED(Tcl_Interp *))		/* Pointer to the calling interp */
{
    (void)dummy;

    ckfree(clientData);
}

/*
 *----------------------------------------------------------------------
 *
 * GetSticky -
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
2389
2390
2391
2392
2393
2394
2395


2396
2397
2398
2399
2400
2401
2402
2403
2404


2405
2406
2407
2408
2409
2410
2411







-
-
+
+







-
-







 *	Creates a new Tcl_Obj.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
GetSticky(
    ClientData dummy,
    Tk_Window tkwin,
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    char *recordPtr,		/* Pointer to widget record. */
    TkSizeT internalOffset)		/* Offset within *recordPtr containing the
				 * sticky value. */
{
    int sticky = *(int *)(recordPtr + internalOffset);
    char buffer[5];
    char *p = &buffer[0];
    (void)dummy;
    (void)tkwin;

    if (sticky & STICK_NORTH) {
	*p++ = 'n';
    }
    if (sticky & STICK_EAST) {
	*p++ = 'e';
    }
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
2437
2438
2439
2440
2441
2442
2443

2444
2445

2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459


2460
2461
2462
2463
2464
2465
2466







-
+

-
+













-
-







 *	specified string was empty and that is acceptable.
 *
 *----------------------------------------------------------------------
 */

static int
SetSticky(
    ClientData dummy,
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interp; may be used for errors. */
    Tk_Window tkwin,		/* Window for which option is being set. */
    TCL_UNUSED(Tk_Window),	/* Window for which option is being set. */
    Tcl_Obj **value,		/* Pointer to the pointer to the value object.
				 * We use a pointer to the pointer because we
				 * may need to return a value (NULL). */
    char *recordPtr,		/* Pointer to storage for the widget record. */
    TkSizeT internalOffset,		/* Offset within *recordPtr at which the
				 * internal value is to be stored. */
    char *oldInternalPtr,	/* Pointer to storage for the old value. */
    int flags)			/* Flags for the option, set Tk_SetOptions. */
{
    int sticky = 0;
    char c;
    void *internalPtr;
    const char *string;
    (void)dummy;
    (void)tkwin;

    internalPtr = ComputeSlotAddress(recordPtr, internalOffset);

    if (flags & TK_OPTION_NULL_OK && ObjectIsEmpty(*value)) {
	*value = NULL;
    } else {
	/*
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
2517
2518
2519
2520
2521
2522
2523


2524
2525
2526
2527
2528



2529
2530
2531
2532
2533
2534
2535
2536
2537


2538
2539
2540
2541

2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558



2559
2560
2561
2562


2563
2564
2565


2566
2567
2568
2569


2570
2571
2572
2573
2574

2575
2576
2577

2578
2579
2580
2581
2582
2583
2584
2585







-
-
+
+



-
-
-









-
-
+
+


-
+
















-
-
-
+
+
+

-
-
+
+

-
-
+
+


-
-
+
+



-
+


-
+







 *	Restores the old value.
 *
 *----------------------------------------------------------------------
 */

static void
RestoreSticky(
    ClientData dummy,
    Tk_Window tkwin,
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    char *internalPtr,		/* Pointer to storage for value. */
    char *oldInternalPtr)	/* Pointer to old value. */
{
    (void)dummy;
    (void)tkwin;

    *(int *)internalPtr = *(int *)oldInternalPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * AdjustForSticky --
 *
 *	Given the x,y coords of the top-left corner of a pane, the dimensions
 *	of that pane, and the dimensions of a slave, compute the x,y coords
 *	and actual dimensions of the slave based on the slave's sticky value.
 *	of that pane, and the dimensions of a pane, compute the x,y coords
 *	and actual dimensions of the pane based on the pane's sticky value.
 *
 * Results:
 *	No direct return; sets the x, y, slaveWidth and slaveHeight to correct
 *	No direct return; sets the x, y, paneWidth and paneHeight to correct
 *	values.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
AdjustForSticky(
    int sticky,			/* Sticky value; see top of file for
				 * definition. */
    int cavityWidth,		/* Width of the cavity. */
    int cavityHeight,		/* Height of the cavity. */
    int *xPtr, int *yPtr,	/* Initially, coordinates of the top-left
				 * corner of cavity; also return values for
				 * actual x, y coords of slave. */
    int *slaveWidthPtr,		/* Slave width. */
    int *slaveHeightPtr)	/* Slave height. */
				 * actual x, y coords of pane. */
    int *paneWidthPtr,		/* Pane width. */
    int *paneHeightPtr)	/* Pane height. */
{
    int diffx = 0;		/* Cavity width - slave width. */
    int diffy = 0;		/* Cavity hight - slave height. */
    int diffx = 0;		/* Cavity width - pane width. */
    int diffy = 0;		/* Cavity hight - pane height. */

    if (cavityWidth > *slaveWidthPtr) {
	diffx = cavityWidth - *slaveWidthPtr;
    if (cavityWidth > *paneWidthPtr) {
	diffx = cavityWidth - *paneWidthPtr;
    }

    if (cavityHeight > *slaveHeightPtr) {
	diffy = cavityHeight - *slaveHeightPtr;
    if (cavityHeight > *paneHeightPtr) {
	diffy = cavityHeight - *paneHeightPtr;
    }

    if ((sticky & STICK_EAST) && (sticky & STICK_WEST)) {
	*slaveWidthPtr += diffx;
	*paneWidthPtr += diffx;
    }
    if ((sticky & STICK_NORTH) && (sticky & STICK_SOUTH)) {
	*slaveHeightPtr += diffy;
	*paneHeightPtr += diffy;
    }
    if (!(sticky & STICK_WEST)) {
	*xPtr += (sticky & STICK_EAST) ? diffx : diffx/2;
    }
    if (!(sticky & STICK_NORTH)) {
	*yPtr += (sticky & STICK_SOUTH) ? diffy : diffy/2;
    }
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
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







-
-
+
+








-
+








-
-
-
+
+
+



-
-
+
+

-
-
+
+









-
+










-
+















-
-
+
+



-
+

-
+













-
+

-
+

-
+







-
-
+
+



-
+

-
+

-
-
-
+
+
+

-
+



-
+

-
+







static void
MoveSash(
    PanedWindow *pwPtr,
    int sash,
    int diff)
{
    int i;
    int expandPane, reduceFirst, reduceLast, reduceIncr, slaveSize, sashOffset;
    Slave *slavePtr;
    int expandPane, reduceFirst, reduceLast, reduceIncr, paneSize, sashOffset;
    Pane *panePtr;
    int stretchReserve = 0;
    int nextSash = sash + 1;
    const int horizontal = (pwPtr->orient == ORIENT_HORIZONTAL);

    if (diff == 0)
	return;

    /*
     * Update the slave sizes with their real sizes.
     * Update the pane sizes with their real sizes.
     */

    if (pwPtr->showHandle && pwPtr->handleSize > pwPtr->sashWidth) {
	sashOffset = ((pwPtr->handleSize - pwPtr->sashWidth) / 2)
		+ pwPtr->sashPad;
    } else {
	sashOffset = pwPtr->sashPad;
    }
    for (i = 0; i < pwPtr->numSlaves; i++) {
	slavePtr = pwPtr->slaves[i];
	if (slavePtr->hide) {
    for (i = 0; i < pwPtr->numPanes; i++) {
	panePtr = pwPtr->panes[i];
	if (panePtr->hide) {
	    continue;
	}
	if (horizontal) {
	    slavePtr->paneWidth = slavePtr->width = slavePtr->sashx
		    - sashOffset - slavePtr->x - (2 * slavePtr->padx);
	    panePtr->paneWidth = panePtr->width = panePtr->sashx
		    - sashOffset - panePtr->x - (2 * panePtr->padx);
	} else {
	    slavePtr->paneHeight = slavePtr->height = slavePtr->sashy
		    - sashOffset - slavePtr->y - (2 * slavePtr->pady);
	    panePtr->paneHeight = panePtr->height = panePtr->sashy
		    - sashOffset - panePtr->y - (2 * panePtr->pady);
	}
    }

    /*
     * There must be a next sash since it is only possible to enter this
     * routine when moving an actual sash which implies there exists a visible
     * pane to either side of the sash.
     */

    while (nextSash < pwPtr->numSlaves-1 && pwPtr->slaves[nextSash]->hide) {
    while (nextSash < pwPtr->numPanes-1 && pwPtr->panes[nextSash]->hide) {
	nextSash++;
    }

    /*
     * Consolidate +/-diff variables to reduce duplicate code.
     */

    if (diff > 0) {
	expandPane = sash;
	reduceFirst = nextSash;
	reduceLast = pwPtr->numSlaves;
	reduceLast = pwPtr->numPanes;
	reduceIncr = 1;
    } else {
	diff = abs(diff);
	expandPane = nextSash;
	reduceFirst = sash;
	reduceLast = -1;
	reduceIncr = -1;
    }

    /*
     * Calculate how much room we have to stretch in and adjust diff value
     * accordingly.
     */

    for (i = reduceFirst; i != reduceLast; i += reduceIncr) {
	slavePtr = pwPtr->slaves[i];
	if (slavePtr->hide) {
	panePtr = pwPtr->panes[i];
	if (panePtr->hide) {
	    continue;
	}
	if (horizontal) {
	    stretchReserve += slavePtr->width - slavePtr->minSize;
	    stretchReserve += panePtr->width - panePtr->minSize;
	} else {
	    stretchReserve += slavePtr->height - slavePtr->minSize;
	    stretchReserve += panePtr->height - panePtr->minSize;
	}
    }
    if (stretchReserve <= 0) {
	return;
    }
    if (diff > stretchReserve) {
	diff = stretchReserve;
    }

    /*
     * Expand pane by diff amount.
     */

    slavePtr = pwPtr->slaves[expandPane];
    panePtr = pwPtr->panes[expandPane];
    if (horizontal) {
	slavePtr->paneWidth = slavePtr->width += diff;
	panePtr->paneWidth = panePtr->width += diff;
    } else {
	slavePtr->paneHeight = slavePtr->height += diff;
	panePtr->paneHeight = panePtr->height += diff;
    }

    /*
     * Reduce panes, respecting minsize, until diff amount has been used.
     */

    for (i = reduceFirst; i != reduceLast; i += reduceIncr) {
	slavePtr = pwPtr->slaves[i];
	if (slavePtr->hide) {
	panePtr = pwPtr->panes[i];
	if (panePtr->hide) {
	    continue;
	}
	if (horizontal) {
	    slaveSize = slavePtr->width;
	    paneSize = panePtr->width;
	} else {
	    slaveSize = slavePtr->height;
	    paneSize = panePtr->height;
	}
	if (diff > (slaveSize - slavePtr->minSize)) {
	    diff -= slaveSize - slavePtr->minSize;
	    slaveSize = slavePtr->minSize;
	if (diff > (paneSize - panePtr->minSize)) {
	    diff -= paneSize - panePtr->minSize;
	    paneSize = panePtr->minSize;
	} else {
	    slaveSize -= diff;
	    paneSize -= diff;
	    i = reduceLast - reduceIncr;
	}
	if (horizontal) {
	    slavePtr->paneWidth = slavePtr->width = slaveSize;
	    panePtr->paneWidth = panePtr->width = paneSize;
	} else {
	    slavePtr->paneHeight = slavePtr->height = slaveSize;
	    panePtr->paneHeight = panePtr->height = paneSize;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
2958
2959
2960
2961
2962
2963
2964
2965

2966
2967

2968
2969
2970
2971
2972
2973
2974
2945
2946
2947
2948
2949
2950
2951

2952
2953

2954
2955
2956
2957
2958
2959
2960
2961







-
+

-
+







	 */

	pwPtr->proxyx = x;
	pwPtr->proxyy = y;

	/*
	 * Make sure the proxy window is higher in the stacking order than the
	 * slaves, so that it will be visible when drawn. It would be more
	 * panes, so that it will be visible when drawn. It would be more
	 * correct to push the proxy window just high enough to appear above
	 * the highest slave, but it's much easier to just force it all the
	 * the highest pane, but it's much easier to just force it all the
	 * way to the top of the stacking order.
	 */

	Tk_RestackWindow(pwPtr->proxywin, Above, NULL);

	/*
	 * Let Tk_MaintainGeometry take care of placing the window at the
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
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







-
-
+
+


-
-
+
+










-
-
+
+







	sashWidth -= 2 * Tk_InternalBorderLeft(pwPtr->tkwin);
	lpad = rpad = 0;
    }

    GetFirstLastVisiblePane(pwPtr, &first, &last);
    isHandle = 0;
    found = -1;
    for (i = 0; i < pwPtr->numSlaves - 1; i++) {
	if (pwPtr->slaves[i]->hide || i == last) {
    for (i = 0; i < pwPtr->numPanes - 1; i++) {
	if (pwPtr->panes[i]->hide || i == last) {
	    continue;
	}
	thisx = pwPtr->slaves[i]->sashx;
	thisy = pwPtr->slaves[i]->sashy;
	thisx = pwPtr->panes[i]->sashx;
	thisy = pwPtr->panes[i]->sashy;

	if (((thisx - lpad) <= x && x <= (thisx + rpad + sashWidth)) &&
		((thisy - tpad) <= y && y <= (thisy + bpad + sashHeight))) {
	    found = i;

	    /*
	     * Determine if the point is over the handle or the sash.
	     */

	    if (pwPtr->showHandle) {
		thisx = pwPtr->slaves[i]->handlex;
		thisy = pwPtr->slaves[i]->handley;
		thisx = pwPtr->panes[i]->handlex;
		thisy = pwPtr->panes[i]->handley;
		if (pwPtr->orient == ORIENT_HORIZONTAL) {
		    if (thisy <= y && y <= (thisy + pwPtr->handleSize)) {
			isHandle = 1;
		    }
		} else {
		    if (thisx <= x && x <= (thisx + pwPtr->handleSize)) {
			isHandle = 1;

Changes to generic/tkPkgConfig.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






-
-
+
+







/*
 * tkPkgConfig.c --
 *
 *	This file contains the configuration information to embed into the tcl
 *	binary library.
 *
 * Copyright (c) 2002 Andreas Kupries <[email protected]>
 * Copyright (c) 2017 Stuart Cassoff <[email protected]>
 * Copyright © 2002 Andreas Kupries <[email protected]>
 * Copyright © 2017 Stuart Cassoff <[email protected]>
 *
 * 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:
36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50







-
+







 *				configuration values.
 */

#include "tkInt.h"


#ifndef TCL_CFGVAL_ENCODING
#define TCL_CFGVAL_ENCODING "ascii"
#define TCL_CFGVAL_ENCODING "utf-8"
#endif

/*
 * Use C preprocessor statements to define the various values for the embedded
 * configuration information.
 */

80
81
82
83
84
85
86
87

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



103
104
105
106
107
108
109
80
81
82
83
84
85
86

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112







-
+















+
+
+








#ifdef TCL_CFG_PROFILED
#  define CFG_PROFILED		"1"
#else
#  define CFG_PROFILED		"0"
#endif

#if defined(_WIN32) || defined(__CYGWIN__)
#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},

Changes to generic/tkPlace.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
1
2
3
4
5
6


7
8
9
10
11
12
13
14
15
16
17
18
19

20
21


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

38
39
40

41
42
43

44
45


46
47
48
49
50
51
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66

67
68
69
70
71

72
73
74

75
76
77
78
79
80
81
82
83
84

85
86




87
88
89
90
91
92

93
94
95

96
97
98

99
100







101
102
103
104
105
106
107
108
109
110
111

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

126
127
128
129




130
131
132
133
134
135
136
137

138
139
140

141
142
143

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

158
159
160
161
162
163

164
165
166
167
168
169
170

171
172

173
174
175
176






177
178
179
180
181
182
183
184

185
186
187
188
189
190
191
192






-
-
+
+











-
+

-
-
+
+














-
+


-
+


-
+

-
-
+
+












-
+






-
+




-
+


-
+









-
+

-
-
-
-
+
+
+
+


-
+


-
+


-
+

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




-
+













-
+



-
-
-
-
+
+
+
+




-
+


-
+


-
+













-
+





-
+






-
+

-
+



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


-
+







/*
 * tkPlace.c --
 *
 *	This file contains code to implement a simple geometry manager for Tk
 *	based on absolute placement or "rubber-sheet" placement.
 *
 * Copyright (c) 1992-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1992-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

/*
 * Border modes for relative placement:
 *
 * BM_INSIDE:		relative distances computed using area inside all
 *			borders of master window.
 *			borders of container window.
 * BM_OUTSIDE:		relative distances computed using outside area that
 *			includes all borders of master.
 * BM_IGNORE:		border issues are ignored: place relative to master's
 *			includes all borders of container.
 * BM_IGNORE:		border issues are ignored: place relative to container's
 *			actual window size.
 */

static const char *const borderModeStrings[] = {
    "inside", "outside", "ignore", NULL
};

typedef enum {BM_INSIDE, BM_OUTSIDE, BM_IGNORE} BorderMode;

/*
 * For each window whose geometry is managed by the placer there is a
 * structure of the following type:
 */

typedef struct Slave {
typedef struct Content {
    Tk_Window tkwin;		/* Tk's token for window. */
    Tk_Window inTkwin;		/* Token for the -in window. */
    struct Master *masterPtr;	/* Pointer to information for window relative
    struct Container *containerPtr;	/* Pointer to information for window relative
				 * to which tkwin is placed. This isn't
				 * necessarily the logical parent of tkwin.
				 * NULL means the master was deleted or never
				 * NULL means the container was deleted or never
				 * assigned. */
    struct Slave *nextPtr;	/* Next in list of windows placed relative to
				 * same master (NULL for end of list). */
    struct Content *nextPtr;	/* Next in list of windows placed relative to
				 * same container (NULL for end of list). */
    Tk_OptionTable optionTable;	/* Table that defines configuration options
				 * available for this command. */
    /*
     * Geometry information for window; where there are both relative and
     * absolute values for the same attribute (e.g. x and relX) only one of
     * them is actually used, depending on flags.
     */

    int x, y;			/* X and Y pixel coordinates for tkwin. */
    Tcl_Obj *xPtr, *yPtr;	/* Tcl_Obj rep's of x, y coords, to keep pixel
				 * spec. information. */
    double relX, relY;		/* X and Y coordinates relative to size of
				 * master. */
				 * container. */
    int width, height;		/* Absolute dimensions for tkwin. */
    Tcl_Obj *widthPtr;		/* Tcl_Obj rep of width, to keep pixel
				 * spec. */
    Tcl_Obj *heightPtr;		/* Tcl_Obj rep of height, to keep pixel
				 * spec. */
    double relWidth, relHeight;	/* Dimensions for tkwin relative to size of
				 * master. */
				 * container. */
    Tcl_Obj *relWidthPtr;
    Tcl_Obj *relHeightPtr;
    Tk_Anchor anchor;		/* Which point on tkwin is placed at the given
				 * position. */
    BorderMode borderMode;	/* How to treat borders of master window. */
    BorderMode borderMode;	/* How to treat borders of container window. */
    int flags;			/* Various flags; see below for bit
				 * definitions. */
} Slave;
} Content;

/*
 * Type masks for options:
 */

#define IN_MASK		1

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_ANCHOR, "-anchor", NULL, NULL, "nw", TCL_INDEX_NONE,
	 offsetof(Slave, anchor), 0, 0, 0},
	 offsetof(Content, anchor), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-bordermode", NULL, NULL, "inside", TCL_INDEX_NONE,
	 offsetof(Slave, borderMode), 0, borderModeStrings, 0},
    {TK_OPTION_PIXELS, "-height", NULL, NULL, "", offsetof(Slave, heightPtr),
	 offsetof(Slave, height), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_WINDOW, "-in", NULL, NULL, "", TCL_INDEX_NONE, offsetof(Slave, inTkwin),
	 offsetof(Content, borderMode), 0, borderModeStrings, 0},
    {TK_OPTION_PIXELS, "-height", NULL, NULL, "", offsetof(Content, heightPtr),
	 offsetof(Content, height), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_WINDOW, "-in", NULL, NULL, "", TCL_INDEX_NONE, offsetof(Content, inTkwin),
	 0, 0, IN_MASK},
    {TK_OPTION_DOUBLE, "-relheight", NULL, NULL, "",
	 offsetof(Slave, relHeightPtr), offsetof(Slave, relHeight),
	 offsetof(Content, relHeightPtr), offsetof(Content, relHeight),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-relwidth", NULL, NULL, "",
	 offsetof(Slave, relWidthPtr), offsetof(Slave, relWidth),
	 offsetof(Content, relWidthPtr), offsetof(Content, relWidth),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-relx", NULL, NULL, "0", TCL_INDEX_NONE,
	 offsetof(Slave, relX), 0, 0, 0},
	 offsetof(Content, relX), 0, 0, 0},
    {TK_OPTION_DOUBLE, "-rely", NULL, NULL, "0", TCL_INDEX_NONE,
	 offsetof(Slave, relY), 0, 0, 0},
    {TK_OPTION_PIXELS, "-width", NULL, NULL, "", offsetof(Slave, widthPtr),
	 offsetof(Slave, width), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-x", NULL, NULL, "0", offsetof(Slave, xPtr),
	 offsetof(Slave, x), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-y", NULL, NULL, "0", offsetof(Slave, yPtr),
	 offsetof(Slave, y), TK_OPTION_NULL_OK, 0, 0},
	 offsetof(Content, relY), 0, 0, 0},
    {TK_OPTION_PIXELS, "-width", NULL, NULL, "", offsetof(Content, widthPtr),
	 offsetof(Content, width), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-x", NULL, NULL, "0", offsetof(Content, xPtr),
	 offsetof(Content, x), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-y", NULL, NULL, "0", offsetof(Content, yPtr),
	 offsetof(Content, y), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

/*
 * Flag definitions for Slave structures:
 * Flag definitions for Content structures:
 *
 * CHILD_WIDTH -		1 means -width was specified;
 * CHILD_REL_WIDTH -		1 means -relwidth was specified.
 * CHILD_HEIGHT -		1 means -height was specified;
 * CHILD_REL_HEIGHT -		1 means -relheight was specified.
 */

#define CHILD_WIDTH		1
#define CHILD_REL_WIDTH		2
#define CHILD_HEIGHT		4
#define CHILD_REL_HEIGHT	8

/*
 * For each master window that has a slave managed by the placer there is a
 * For each container window that has a content managed by the placer there is a
 * structure of the following form:
 */

typedef struct Master {
    Tk_Window tkwin;		/* Tk's token for master window. */
    struct Slave *slavePtr;	/* First in linked list of slaves placed
				 * relative to this master. */
typedef struct Container {
    Tk_Window tkwin;		/* Tk's token for container window. */
    struct Content *contentPtr;	/* First in linked list of content windowslaced
				 * relative to this container. */
    int *abortPtr;		/* If non-NULL, it means that there is a nested
				 * call to RecomputePlacement already working on
				 * this window.  *abortPtr may be set to 1 to
				 * abort that nested call.  This happens, for
				 * example, if tkwin or any of its slaves
				 * example, if tkwin or any of its content
				 * is deleted. */
    int flags;			/* See below for bit definitions. */
} Master;
} Container;

/*
 * Flag definitions for masters:
 * Flag definitions for containers:
 *
 * PARENT_RECONFIG_PENDING -	1 means that a call to RecomputePlacement is
 *				already pending via a Do_When_Idle handler.
 */

#define PARENT_RECONFIG_PENDING	1

/*
 * The following structure is the official type record for the placer:
 */

static void		PlaceRequestProc(ClientData clientData,
			    Tk_Window tkwin);
static void		PlaceLostSlaveProc(ClientData clientData,
static void		PlaceLostContentProc(ClientData clientData,
			    Tk_Window tkwin);

static const Tk_GeomMgr placerType = {
    "place",			/* name */
    PlaceRequestProc,		/* requestProc */
    PlaceLostSlaveProc,		/* lostSlaveProc */
    PlaceLostContentProc,		/* lostContentProc */
};

/*
 * Forward declarations for functions defined later in this file:
 */

static void		SlaveStructureProc(ClientData clientData,
static void		ContentStructureProc(ClientData clientData,
			    XEvent *eventPtr);
static int		ConfigureSlave(Tcl_Interp *interp, Tk_Window tkwin,
static int		ConfigureContent(Tcl_Interp *interp, Tk_Window tkwin,
			    Tk_OptionTable table, int objc,
			    Tcl_Obj *const objv[]);
static int		PlaceInfoCommand(Tcl_Interp *interp, Tk_Window tkwin);
static Slave *		CreateSlave(Tk_Window tkwin, Tk_OptionTable table);
static void		FreeSlave(Slave *slavePtr);
static Slave *		FindSlave(Tk_Window tkwin);
static Master *		CreateMaster(Tk_Window tkwin);
static Master *		FindMaster(Tk_Window tkwin);
static void		MasterStructureProc(ClientData clientData,
static Content *		CreateContent(Tk_Window tkwin, Tk_OptionTable table);
static void		FreeContent(Content *contentPtr);
static Content *		FindContent(Tk_Window tkwin);
static Container *		CreateContainer(Tk_Window tkwin);
static Container *		FindContainer(Tk_Window tkwin);
static void		PlaceStructureProc(ClientData clientData,
			    XEvent *eventPtr);
static void		RecomputePlacement(ClientData clientData);
static void		UnlinkSlave(Slave *slavePtr);
static void		UnlinkContent(Content *contentPtr);

/*
 *--------------------------------------------------------------
 *
 * Tk_PlaceObjCmd --
 *
 *	This function is invoked to process the "place" Tcl commands. See the
206
207
208
209
210
211
212
213

214
215
216



217

218
219

220
221
222
223
224
225
226
206
207
208
209
210
211
212

213
214
215
216
217
218
219

220
221

222
223
224
225
226
227
228
229







-
+



+
+
+
-
+

-
+







    ClientData clientData,	/* Interpreter main window. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window main_win = (Tk_Window)clientData;
    Tk_Window tkwin;
    Slave *slavePtr;
    Content *contentPtr;
    TkDisplay *dispPtr;
    Tk_OptionTable optionTable;
    static const char *const optionStrings[] = {
	"configure", "content", "forget", "info", "slaves", NULL
    };
    static const char *const optionStringsNoDep[] = {
	"configure", "forget", "info", "slaves", NULL
	"configure", "content", "forget", "info", NULL
    };
    enum options { PLACE_CONFIGURE, PLACE_FORGET, PLACE_INFO, PLACE_SLAVES };
    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;
    }

243
244
245
246
247
248
249
250
251


252
253
254
255

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


276
277
278
279
280








281
282
283
284
285
286
287
288
289
290


291
292
293

294
295
296
297
298
299
300
301

302
303
304
305
306
307
308
309


310
311
312
313
314



315
316
317


318
319
320


321
322
323

324
325
326
327
328
329
330
331
332
333
334



335
336
337
338
339
340
341


342
343
344
345


346
347

348
349
350
351
352
353
354
355
356
357
358
359
360
361

362
363

364
365
366
367

368
369
370

371
372
373
374
375
376
377



378
379
380
381

382
383
384
385

386
387

388
389
390
391

392
393
394
395
396
397
398
399
400
401
402
403
404
405











406
407
408
409
410
411

412
413

414
415
416
417
418
419
420
421
422
423
424
425
426


427
428
429
430



431
432
433
434
435
436

437
438

439
440
441
442
443

444
445
446
447
448
449
450
451
452
453



454
455
456
457
458

459
460
461
462

463
464
465
466
467
468

469
470
471


472
473
474
475
476
477

478
479
480
481
482
483
484


485
486
487


488
489
490


491
492
493
494


495
496

497
498

499
500
501


502
503
504
505
506
507
508


509
510

511
512
513
514
515
516

517
518

519
520
521
522

523
524
525

526
527
528
529
530
531
532



533
534
535

536
537
538
539

540
541
542
543
544
545
546
547
548








549
550

551
552

553
554
555
556
557
558

559
560

561
562
563
564
565

566
567
568
569
570
571
572
573
574
575
576



577
578
579
580
581

582
583
584
585

586
587
588
589
590
591

592
593
594
595
596
597
598
599
600
601

602
603
604
605
606
607
608

609
610
611
612
613
614
615

616
617
618
619
620



621
622
623
624
625
626
627
628
629
630

631
632
633


634
635
636
637
638

639
640
641
642
643



644
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
246
247
248
249
250
251
252


253
254
255
256
257

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


277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299


300
301
302
303

304
305
306
307
308
309
310
311

312
313
314
315
316
317
318


319
320
321
322



323
324
325
326


327
328
329


330
331
332
333

334
335
336
337
338
339
340
341
342
343


344
345
346
347
348
349
350
351


352
353
354
355


356
357
358

359
360
361
362
363
364
365
366
367
368
369
370
371
372

373
374

375
376
377
378

379
380
381

382
383
384
385
386



387
388
389
390
391
392

393
394
395
396

397
398

399
400
401
402

403
404
405
406











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

423
424

425
426
427
428
429
430
431
432
433
434
435
436


437
438
439



440
441
442
443
444
445
446
447

448
449

450
451
452
453
454

455
456
457
458
459
460
461
462



463
464
465
466
467
468
469

470
471
472
473

474
475
476
477
478
479

480
481


482
483
484
485
486
487
488

489
490
491
492
493
494


495
496
497


498
499
500


501
502
503
504


505
506
507

508
509

510
511


512
513
514
515
516
517
518


519
520
521

522
523
524
525
526
527

528
529

530
531
532
533

534
535
536

537
538
539
540
541



542
543
544
545
546

547
548
549
550

551
552








553
554
555
556
557
558
559
560
561

562
563

564
565
566
567
568
569

570
571

572
573
574
575
576

577
578
579
580
581
582
583
584
585



586
587
588
589
590
591
592

593
594
595
596

597
598
599
600
601
602

603
604
605
606
607
608
609
610
611
612

613
614
615
616
617
618
619

620
621
622
623
624
625
626

627
628
629



630
631
632
633
634
635
636
637
638
639
640
641

642
643


644
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







-
-
+
+



-
+


















-
-
+
+





+
+
+
+
+
+
+
+








-
-
+
+


-
+







-
+






-
-
+
+


-
-
-
+
+
+

-
-
+
+

-
-
+
+


-
+









-
-
+
+
+





-
-
+
+


-
-
+
+

-
+













-
+

-
+



-
+


-
+




-
-
-
+
+
+



-
+



-
+

-
+



-
+



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





-
+

-
+











-
-
+
+

-
-
-
+
+
+





-
+

-
+




-
+







-
-
-
+
+
+




-
+



-
+





-
+

-
-
+
+





-
+





-
-
+
+

-
-
+
+

-
-
+
+


-
-
+
+

-
+

-
+

-
-
+
+





-
-
+
+

-
+





-
+

-
+



-
+


-
+




-
-
-
+
+
+


-
+



-
+

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

-
+

-
+





-
+

-
+




-
+








-
-
-
+
+
+




-
+



-
+





-
+









-
+






-
+






-
+


-
-
-
+
+
+









-
+

-
-
+
+




-
+


-
-
-
+
+
+


-
-
+
+


-
-
+
+


-
-
+
+


-
+

-
+



-
+



-
+


-
+


-
-
+
+



-
-
+
+




-
-
+
+




-
+

-
-
+
+








-
-
-
+
+
+

-
-
+
+




-
-
+
+


-
-
+
+

-
+


-
+


-
-
-
+
+
+

-
-
+
+



-
+


-
-
-
+
+
+



-
+


-
-
-
-
-
+
+
+
+
+


-
+





-
-
-
+
+
+








	/*
	 * Initialize, if that hasn't been done yet.
	 */

	dispPtr = ((TkWindow *) tkwin)->dispPtr;
	if (!dispPtr->placeInit) {
	    Tcl_InitHashTable(&dispPtr->masterTable, TCL_ONE_WORD_KEYS);
	    Tcl_InitHashTable(&dispPtr->slaveTable, TCL_ONE_WORD_KEYS);
	    Tcl_InitHashTable(&dispPtr->containerTable, TCL_ONE_WORD_KEYS);
	    Tcl_InitHashTable(&dispPtr->contentTable, TCL_ONE_WORD_KEYS);
	    dispPtr->placeInit = 1;
	}

	return ConfigureSlave(interp, tkwin, optionTable, objc-2, objv+2);
	return ConfigureContent(interp, tkwin, optionTable, objc-2, objv+2);
    }

    /*
     * Handle more general case of option followed by window name followed by
     * possible additional arguments.
     */

    if (TkGetWindowFromObj(interp, main_win, objv[2],
	    &tkwin) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Initialize, if that hasn't been done yet.
     */

    dispPtr = ((TkWindow *) tkwin)->dispPtr;
    if (!dispPtr->placeInit) {
	Tcl_InitHashTable(&dispPtr->masterTable, TCL_ONE_WORD_KEYS);
	Tcl_InitHashTable(&dispPtr->slaveTable, TCL_ONE_WORD_KEYS);
	Tcl_InitHashTable(&dispPtr->containerTable, TCL_ONE_WORD_KEYS);
	Tcl_InitHashTable(&dispPtr->contentTable, TCL_ONE_WORD_KEYS);
	dispPtr->placeInit = 1;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	/*
	 * Call it again without the deprecated ones to get a proper error
	 * message. This works well since there can't be any ambiguity between
	 * deprecated and new options.
	 */

	Tcl_GetIndexFromObjStruct(interp, objv[1], optionStringsNoDep,
		sizeof(char *), "option", 0, &index);
	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case PLACE_CONFIGURE:
	if (objc == 3 || objc == 4) {
	    Tcl_Obj *objPtr;

	    slavePtr = FindSlave(tkwin);
	    if (slavePtr == NULL) {
	    contentPtr = FindContent(tkwin);
	    if (contentPtr == NULL) {
		return TCL_OK;
	    }
	    objPtr = Tk_GetOptionInfo(interp, slavePtr, optionTable,
	    objPtr = Tk_GetOptionInfo(interp, contentPtr, optionTable,
		    (objc == 4) ? objv[3] : NULL, tkwin);
	    if (objPtr == NULL) {
		return TCL_ERROR;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	    return TCL_OK;
	}
	return ConfigureSlave(interp, tkwin, optionTable, objc-3, objv+3);
	return ConfigureContent(interp, tkwin, optionTable, objc-3, objv+3);

    case PLACE_FORGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "pathName");
	    return TCL_ERROR;
	}
	slavePtr = FindSlave(tkwin);
	if (slavePtr == NULL) {
	contentPtr = FindContent(tkwin);
	if (contentPtr == NULL) {
	    return TCL_OK;
	}
	if ((slavePtr->masterPtr != NULL) &&
		(slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin))) {
	    Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin);
	if ((contentPtr->containerPtr != NULL) &&
		(contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin))) {
	    Tk_UnmaintainGeometry(contentPtr->tkwin, contentPtr->containerPtr->tkwin);
	}
	UnlinkSlave(slavePtr);
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable,
	UnlinkContent(contentPtr);
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->contentTable,
		tkwin));
	Tk_DeleteEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc,
		slavePtr);
	Tk_DeleteEventHandler(tkwin, StructureNotifyMask, ContentStructureProc,
		contentPtr);
	Tk_ManageGeometry(tkwin, NULL, NULL);
	Tk_UnmapWindow(tkwin);
	FreeSlave(slavePtr);
	FreeContent(contentPtr);
	break;

    case PLACE_INFO:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "pathName");
	    return TCL_ERROR;
	}
	return PlaceInfoCommand(interp, tkwin);

    case PLACE_SLAVES: {
	Master *masterPtr;
    case PLACE_SLAVES:
    case PLACE_CONTENT: {
	Container *containerPtr;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "pathName");
	    return TCL_ERROR;
	}
	masterPtr = FindMaster(tkwin);
	if (masterPtr != NULL) {
	containerPtr = FindContainer(tkwin);
	if (containerPtr != NULL) {
	    Tcl_Obj *listPtr = Tcl_NewObj();

	    for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
		    slavePtr = slavePtr->nextPtr) {
	    for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
		    contentPtr = contentPtr->nextPtr) {
		Tcl_ListObjAppendElement(NULL, listPtr,
			TkNewWindowObj(slavePtr->tkwin));
			Tk_NewWindowObj(contentPtr->tkwin));
	    }
	    Tcl_SetObjResult(interp, listPtr);
	}
	break;
    }
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * CreateSlave --
 * CreateContent --
 *
 *	Given a Tk_Window token, find the Slave structure corresponding to
 *	Given a Tk_Window token, find the Content structure corresponding to
 *	that token, creating a new one if necessary.
 *
 * Results:
 *	Pointer to the Slave structure.
 *	Pointer to the Content structure.
 *
 * Side effects:
 *	A new Slave structure may be created.
 *	A new Content structure may be created.
 *
 *----------------------------------------------------------------------
 */

static Slave *
CreateSlave(
    Tk_Window tkwin,		/* Token for desired slave. */
static Content *
CreateContent(
    Tk_Window tkwin,		/* Token for desired content. */
    Tk_OptionTable table)
{
    Tcl_HashEntry *hPtr;
    Slave *slavePtr;
    Content *contentPtr;
    int isNew;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    hPtr = Tcl_CreateHashEntry(&dispPtr->slaveTable, (char *) tkwin, &isNew);
    hPtr = Tcl_CreateHashEntry(&dispPtr->contentTable, (char *) tkwin, &isNew);
    if (!isNew) {
	return (Slave *)Tcl_GetHashValue(hPtr);
	return (Content *)Tcl_GetHashValue(hPtr);
    }

    /*
     * No preexisting slave structure for that window, so make a new one and
     * No preexisting content structure for that window, so make a new one and
     * populate it with some default values.
     */

    slavePtr = (Slave *)ckalloc(sizeof(Slave));
    memset(slavePtr, 0, sizeof(Slave));
    slavePtr->tkwin = tkwin;
    slavePtr->inTkwin = NULL;
    slavePtr->anchor = TK_ANCHOR_NW;
    slavePtr->borderMode = BM_INSIDE;
    slavePtr->optionTable = table;
    Tcl_SetHashValue(hPtr, slavePtr);
    Tk_CreateEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc,
	    slavePtr);
    return slavePtr;
    contentPtr = (Content *)ckalloc(sizeof(Content));
    memset(contentPtr, 0, sizeof(Content));
    contentPtr->tkwin = tkwin;
    contentPtr->inTkwin = NULL;
    contentPtr->anchor = TK_ANCHOR_NW;
    contentPtr->borderMode = BM_INSIDE;
    contentPtr->optionTable = table;
    Tcl_SetHashValue(hPtr, contentPtr);
    Tk_CreateEventHandler(tkwin, StructureNotifyMask, ContentStructureProc,
	    contentPtr);
    return contentPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeSlave --
 * FreeContent --
 *
 *	Frees the resources held by a Slave structure.
 *	Frees the resources held by a Content structure.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	Memory are freed.
 *
 *----------------------------------------------------------------------
 */

static void
FreeSlave(
    Slave *slavePtr)
FreeContent(
    Content *contentPtr)
{
    Tk_FreeConfigOptions((char *) slavePtr, slavePtr->optionTable,
	    slavePtr->tkwin);
    ckfree(slavePtr);
    Tk_FreeConfigOptions((char *) contentPtr, contentPtr->optionTable,
	    contentPtr->tkwin);
    ckfree(contentPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * FindSlave --
 * FindContent --
 *
 *	Given a Tk_Window token, find the Slave structure corresponding to
 *	Given a Tk_Window token, find the Content structure corresponding to
 *	that token. This is purely a lookup function; it will not create a
 *	record if one does not yet exist.
 *
 * Results:
 *	Pointer to Slave structure; NULL if none exists.
 *	Pointer to Content structure; NULL if none exists.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Slave *
FindSlave(
    Tk_Window tkwin)		/* Token for desired slave. */
static Content *
FindContent(
    Tk_Window tkwin)		/* Token for desired content. */
{
    Tcl_HashEntry *hPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    hPtr = Tcl_FindHashEntry(&dispPtr->slaveTable, tkwin);
    hPtr = Tcl_FindHashEntry(&dispPtr->contentTable, tkwin);
    if (hPtr == NULL) {
	return NULL;
    }
    return (Slave *)Tcl_GetHashValue(hPtr);
    return (Content *)Tcl_GetHashValue(hPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * UnlinkSlave --
 * UnlinkContent --
 *
 *	This function removes a slave window from the chain of slaves in its
 *	master.
 *	This function removes a content window from the chain of content windows in its
 *	container.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The slave list of slavePtr's master changes.
 *	The content list of contentPtr's container changes.
 *
 *----------------------------------------------------------------------
 */

static void
UnlinkSlave(
    Slave *slavePtr)		/* Slave structure to be unlinked. */
UnlinkContent(
    Content *contentPtr)		/* Content structure to be unlinked. */
{
    Master *masterPtr;
    Slave *prevPtr;
    Container *containerPtr;
    Content *prevPtr;

    masterPtr = slavePtr->masterPtr;
    if (masterPtr == NULL) {
    containerPtr = contentPtr->containerPtr;
    if (containerPtr == NULL) {
	return;
    }
    if (masterPtr->slavePtr == slavePtr) {
	masterPtr->slavePtr = slavePtr->nextPtr;
    if (containerPtr->contentPtr == contentPtr) {
	containerPtr->contentPtr = contentPtr->nextPtr;
    } else {
	for (prevPtr = masterPtr->slavePtr; ; prevPtr = prevPtr->nextPtr) {
	for (prevPtr = containerPtr->contentPtr; ; prevPtr = prevPtr->nextPtr) {
	    if (prevPtr == NULL) {
		Tcl_Panic("UnlinkSlave couldn't find slave to unlink");
		Tcl_Panic("UnlinkContent couldn't find content to unlink");
	    }
	    if (prevPtr->nextPtr == slavePtr) {
		prevPtr->nextPtr = slavePtr->nextPtr;
	    if (prevPtr->nextPtr == contentPtr) {
		prevPtr->nextPtr = contentPtr->nextPtr;
		break;
	    }
	}
    }

    if (masterPtr->abortPtr != NULL) {
	*masterPtr->abortPtr = 1;
    if (containerPtr->abortPtr != NULL) {
	*containerPtr->abortPtr = 1;
    }
    slavePtr->masterPtr = NULL;
    contentPtr->containerPtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * CreateMaster --
 * CreateContainer --
 *
 *	Given a Tk_Window token, find the Master structure corresponding to
 *	Given a Tk_Window token, find the Container structure corresponding to
 *	that token, creating a new one if necessary.
 *
 * Results:
 *	Pointer to the Master structure.
 *	Pointer to the Container structure.
 *
 * Side effects:
 *	A new Master structure may be created.
 *	A new Container structure may be created.
 *
 *----------------------------------------------------------------------
 */

static Master *
CreateMaster(
    Tk_Window tkwin)		/* Token for desired master. */
static Container *
CreateContainer(
    Tk_Window tkwin)		/* Token for desired container. */
{
    Tcl_HashEntry *hPtr;
    Master *masterPtr;
    Container *containerPtr;
    int isNew;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    hPtr = Tcl_CreateHashEntry(&dispPtr->masterTable, (char *) tkwin, &isNew);
    hPtr = Tcl_CreateHashEntry(&dispPtr->containerTable, (char *)tkwin, &isNew);
    if (isNew) {
	masterPtr = (Master *)ckalloc(sizeof(Master));
	masterPtr->tkwin = tkwin;
	masterPtr->slavePtr = NULL;
	masterPtr->abortPtr = NULL;
	masterPtr->flags = 0;
	Tcl_SetHashValue(hPtr, masterPtr);
	Tk_CreateEventHandler(masterPtr->tkwin, StructureNotifyMask,
		MasterStructureProc, masterPtr);
	containerPtr = (Container *)ckalloc(sizeof(Container));
	containerPtr->tkwin = tkwin;
	containerPtr->contentPtr = NULL;
	containerPtr->abortPtr = NULL;
	containerPtr->flags = 0;
	Tcl_SetHashValue(hPtr, containerPtr);
	Tk_CreateEventHandler(containerPtr->tkwin, StructureNotifyMask,
		PlaceStructureProc, containerPtr);
    } else {
	masterPtr = (Master *)Tcl_GetHashValue(hPtr);
	containerPtr = (Container *)Tcl_GetHashValue(hPtr);
    }
    return masterPtr;
    return containerPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * FindMaster --
 * FindContainer --
 *
 *	Given a Tk_Window token, find the Master structure corresponding to
 *	Given a Tk_Window token, find the Container structure corresponding to
 *	that token. This is simply a lookup function; a new record will not be
 *	created if one does not already exist.
 *
 * Results:
 *	Pointer to the Master structure; NULL if one does not exist for the
 *	Pointer to the Container structure; NULL if one does not exist for the
 *	given Tk_Window token.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Master *
FindMaster(
    Tk_Window tkwin)		/* Token for desired master. */
static Container *
FindContainer(
    Tk_Window tkwin)		/* Token for desired container. */
{
    Tcl_HashEntry *hPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    hPtr = Tcl_FindHashEntry(&dispPtr->masterTable, tkwin);
    hPtr = Tcl_FindHashEntry(&dispPtr->containerTable, tkwin);
    if (hPtr == NULL) {
	return NULL;
    }
    return (Master *)Tcl_GetHashValue(hPtr);
    return (Container *)Tcl_GetHashValue(hPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureSlave --
 * ConfigureContent --
 *
 *	This function is called to process an argv/argc list to reconfigure
 *	the placement of a window.
 *
 * Results:
 *	A standard Tcl result. If an error occurs then a message is left in
 *	the interp's result.
 *
 * Side effects:
 *	Information in slavePtr may change, and slavePtr's master is scheduled
 *	Information in contentPtr may change, and contentPtr's container is scheduled
 *	for reconfiguration.
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureSlave(
ConfigureContent(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Window tkwin,		/* Token for the window to manipulate. */
    Tk_OptionTable table,	/* Token for option table. */
    int objc,			/* Number of config arguments. */
    Tcl_Obj *const objv[])	/* Object values for arguments. */
{
    Master *masterPtr;
    Container *containerPtr;
    Tk_SavedOptions savedOptions;
    int mask;
    Slave *slavePtr;
    Tk_Window masterWin = NULL;
    TkWindow *master;
    Content *contentPtr;
    Tk_Window containerWin = NULL;
    TkWindow *container;

    if (Tk_TopWinHierarchy(tkwin)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't use placer on top-level window \"%s\"; use "
		"wm command instead", Tk_PathName(tkwin)));
	Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "TOPLEVEL", NULL);
	return TCL_ERROR;
    }

    slavePtr = CreateSlave(tkwin, table);
    contentPtr = CreateContent(tkwin, table);

    if (Tk_SetOptions(interp, slavePtr, table, objc, objv,
	    slavePtr->tkwin, &savedOptions, &mask) != TCL_OK) {
    if (Tk_SetOptions(interp, contentPtr, table, objc, objv,
	    contentPtr->tkwin, &savedOptions, &mask) != TCL_OK) {
	goto error;
    }

    /*
     * Set slave flags. First clear the field, then add bits as needed.
     * Set content flags. First clear the field, then add bits as needed.
     */

    slavePtr->flags = 0;
    if (slavePtr->heightPtr) {
	slavePtr->flags |= CHILD_HEIGHT;
    contentPtr->flags = 0;
    if (contentPtr->heightPtr) {
	contentPtr->flags |= CHILD_HEIGHT;
    }

    if (slavePtr->relHeightPtr) {
	slavePtr->flags |= CHILD_REL_HEIGHT;
    if (contentPtr->relHeightPtr) {
	contentPtr->flags |= CHILD_REL_HEIGHT;
    }

    if (slavePtr->relWidthPtr) {
	slavePtr->flags |= CHILD_REL_WIDTH;
    if (contentPtr->relWidthPtr) {
	contentPtr->flags |= CHILD_REL_WIDTH;
    }

    if (slavePtr->widthPtr) {
	slavePtr->flags |= CHILD_WIDTH;
    if (contentPtr->widthPtr) {
	contentPtr->flags |= CHILD_WIDTH;
    }

    if (!(mask & IN_MASK) && (slavePtr->masterPtr != NULL)) {
    if (!(mask & IN_MASK) && (contentPtr->containerPtr != NULL)) {
	/*
	 * If no -in option was passed and the slave is already placed then
	 * If no -in option was passed and the content is already placed then
	 * just recompute the placement.
	 */

	masterPtr = slavePtr->masterPtr;
	containerPtr = contentPtr->containerPtr;
	goto scheduleLayout;
    } else if (mask & IN_MASK) {
	/* -in changed */
	Tk_Window tkwin;
	Tk_Window win;
	Tk_Window ancestor;

	tkwin = slavePtr->inTkwin;
	win = contentPtr->inTkwin;

	/*
	 * Make sure that the new master is either the logical parent of the
	 * slave or a descendant of that window, and that the master and slave
	 * Make sure that the new container is either the logical parent of the
	 * content window or a descendant of that window, and that the container and content
	 * aren't the same.
	 */

	for (ancestor = tkwin; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == Tk_Parent(slavePtr->tkwin)) {
	for (ancestor = win; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == Tk_Parent(contentPtr->tkwin)) {
		break;
	    }
	    if (Tk_TopWinHierarchy(ancestor)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't place %s relative to %s",
			Tk_PathName(slavePtr->tkwin), Tk_PathName(tkwin)));
			"can't place \"%s\" relative to \"%s\"",
			Tk_PathName(contentPtr->tkwin), Tk_PathName(win)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL);
		goto error;
	    }
	}
	if (slavePtr->tkwin == tkwin) {
	if (contentPtr->tkwin == win) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't place %s relative to itself",
		    Tk_PathName(slavePtr->tkwin)));
		    "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 (master = (TkWindow *)tkwin; master != NULL;
	     master = (TkWindow *)TkGetGeomMaster(master)) {
	    if (master == (TkWindow *)slavePtr->tkwin) {
	for (container = (TkWindow *)win; container != NULL;
	     container = (TkWindow *)TkGetContainer(container)) {
	    if (container == (TkWindow *)contentPtr->tkwin) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't put %s inside %s, would cause management loop",
	            Tk_PathName(slavePtr->tkwin), Tk_PathName(tkwin)));
		    "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 (tkwin != Tk_Parent(slavePtr->tkwin)) {
	    ((TkWindow *)slavePtr->tkwin)->maintainerPtr = (TkWindow *)tkwin;
	if (win != Tk_Parent(contentPtr->tkwin)) {
	    ((TkWindow *)contentPtr->tkwin)->maintainerPtr = (TkWindow *)win;
	}

	if ((slavePtr->masterPtr != NULL)
		&& (slavePtr->masterPtr->tkwin == tkwin)) {
	if ((contentPtr->containerPtr != NULL)
		&& (contentPtr->containerPtr->tkwin == win)) {
	    /*
	     * Re-using same old master. Nothing to do.
	     * Re-using same old container. Nothing to do.
	     */

	    masterPtr = slavePtr->masterPtr;
	    containerPtr = contentPtr->containerPtr;
	    goto scheduleLayout;
	}
	if ((slavePtr->masterPtr != NULL) &&
		(slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin))) {
	    Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin);
	if ((contentPtr->containerPtr != NULL) &&
		(contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin))) {
	    Tk_UnmaintainGeometry(contentPtr->tkwin, contentPtr->containerPtr->tkwin);
	}
	UnlinkSlave(slavePtr);
	masterWin = tkwin;
	UnlinkContent(contentPtr);
	containerWin = win;
    }

    /*
     * If there's no master specified for this slave, use its Tk_Parent.
     * If there's no container specified for this content, use its Tk_Parent.
     */

    if (masterWin == NULL) {
	masterWin = Tk_Parent(slavePtr->tkwin);
	slavePtr->inTkwin = masterWin;
    if (containerWin == NULL) {
	containerWin = Tk_Parent(contentPtr->tkwin);
	contentPtr->inTkwin = containerWin;
    }

    /*
     * Manage the slave window in this master.
     * Manage the content window in this container.
     */

    masterPtr = CreateMaster(masterWin);
    slavePtr->masterPtr = masterPtr;
    slavePtr->nextPtr = masterPtr->slavePtr;
    masterPtr->slavePtr = slavePtr;
    Tk_ManageGeometry(slavePtr->tkwin, &placerType, slavePtr);
    containerPtr = CreateContainer(containerWin);
    contentPtr->containerPtr = containerPtr;
    contentPtr->nextPtr = containerPtr->contentPtr;
    containerPtr->contentPtr = contentPtr;
    Tk_ManageGeometry(contentPtr->tkwin, &placerType, contentPtr);

    /*
     * Arrange for the master to be re-arranged at the first idle moment.
     * Arrange for the container to be re-arranged at the first idle moment.
     */

  scheduleLayout:
    Tk_FreeSavedOptions(&savedOptions);

    if (!(masterPtr->flags & PARENT_RECONFIG_PENDING)) {
	masterPtr->flags |= PARENT_RECONFIG_PENDING;
	Tcl_DoWhenIdle(RecomputePlacement, masterPtr);
    if (!(containerPtr->flags & PARENT_RECONFIG_PENDING)) {
	containerPtr->flags |= PARENT_RECONFIG_PENDING;
	Tcl_DoWhenIdle(RecomputePlacement, containerPtr);
    }
    return TCL_OK;

    /*
     * Error while processing some option, cleanup and return.
     */

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
803
804
805
806
807
808
809

810
811
812


813
814
815
816
817

818
819
820

821
822
823
824
825



826
827
828
829
830
831

832
833

834
835
836
837


838
839
840
841
842

843
844

845
846
847
848
849
850


851
852
853
854
855
856
857
858
859
860
861
862

863
864
865
866
867
868
869
870
871
872
873
874
875

876
877


878
879
880

881
882
883
884
885

886
887
888
889
890
891
892
893


894
895
896

897
898

899
900
901


902
903
904
905
906
907


908
909
910

911
912
913
914













915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930


931
932
933
934

935
936

937
938

939
940


941
942
943

944
945
946
947
948
949
950
951
952

953
954
955
956
957


958
959
960

961
962


963
964
965

966
967
968
969
970

971
972
973
974
975


976
977
978
979
980
981


982
983
984
985

986
987
988
989
990
991
992
993







-
+


-
-
+
+



-
+


-
+




-
-
-
+
+
+



-
+

-
+



-
-
+
+



-
+

-
+





-
-
+
+










-
+












-
+

-
-
+
+

-
+




-
+







-
-
+
+

-
+

-
+


-
-
+
+




-
-
+
+

-
+



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



-
-
+
+


-
+

-
+

-
+

-
-
+
+

-
+








-
+




-
-
+
+

-
+

-
-
+
+

-
+




-
+




-
-
+
+




-
-
+
+


-
+







 */

static int
PlaceInfoCommand(
    Tcl_Interp *interp,		/* Interp into which to place result. */
    Tk_Window tkwin)		/* Token for the window to get info on. */
{
    Slave *slavePtr;
    Content *contentPtr;
    Tcl_Obj *infoObj;

    slavePtr = FindSlave(tkwin);
    if (slavePtr == NULL) {
    contentPtr = FindContent(tkwin);
    if (contentPtr == NULL) {
	return TCL_OK;
    }
    infoObj = Tcl_NewObj();
    if (slavePtr->masterPtr != NULL) {
    if (contentPtr->containerPtr != NULL) {
	Tcl_AppendToObj(infoObj, "-in", -1);
	Tcl_ListObjAppendElement(NULL, infoObj,
		TkNewWindowObj(slavePtr->masterPtr->tkwin));
		Tk_NewWindowObj(contentPtr->containerPtr->tkwin));
	Tcl_AppendToObj(infoObj, " ", -1);
    }
    Tcl_AppendPrintfToObj(infoObj,
	    "-x %d -relx %.4g -y %d -rely %.4g",
	    slavePtr->x, slavePtr->relX, slavePtr->y, slavePtr->relY);
    if (slavePtr->flags & CHILD_WIDTH) {
	Tcl_AppendPrintfToObj(infoObj, " -width %d", slavePtr->width);
	    contentPtr->x, contentPtr->relX, contentPtr->y, contentPtr->relY);
    if (contentPtr->flags & CHILD_WIDTH) {
	Tcl_AppendPrintfToObj(infoObj, " -width %d", contentPtr->width);
    } else {
	Tcl_AppendToObj(infoObj, " -width {}", -1);
    }
    if (slavePtr->flags & CHILD_REL_WIDTH) {
    if (contentPtr->flags & CHILD_REL_WIDTH) {
	Tcl_AppendPrintfToObj(infoObj,
		" -relwidth %.4g", slavePtr->relWidth);
		" -relwidth %.4g", contentPtr->relWidth);
    } else {
	Tcl_AppendToObj(infoObj, " -relwidth {}", -1);
    }
    if (slavePtr->flags & CHILD_HEIGHT) {
	Tcl_AppendPrintfToObj(infoObj, " -height %d", slavePtr->height);
    if (contentPtr->flags & CHILD_HEIGHT) {
	Tcl_AppendPrintfToObj(infoObj, " -height %d", contentPtr->height);
    } else {
	Tcl_AppendToObj(infoObj, " -height {}", -1);
    }
    if (slavePtr->flags & CHILD_REL_HEIGHT) {
    if (contentPtr->flags & CHILD_REL_HEIGHT) {
	Tcl_AppendPrintfToObj(infoObj,
		" -relheight %.4g", slavePtr->relHeight);
		" -relheight %.4g", contentPtr->relHeight);
    } else {
	Tcl_AppendToObj(infoObj, " -relheight {}", -1);
    }

    Tcl_AppendPrintfToObj(infoObj, " -anchor %s -bordermode %s",
	    Tk_NameOfAnchor(slavePtr->anchor),
	    borderModeStrings[slavePtr->borderMode]);
	    Tk_NameOfAnchor(contentPtr->anchor),
	    borderModeStrings[contentPtr->borderMode]);
    Tcl_SetObjResult(interp, infoObj);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * RecomputePlacement --
 *
 *	This function is called as a when-idle handler. It recomputes the
 *	geometries of all the slaves of a given master.
 *	geometries of all the content of a given container.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Windows may change size or shape.
 *
 *----------------------------------------------------------------------
 */

static void
RecomputePlacement(
    ClientData clientData)	/* Pointer to Master record. */
    ClientData clientData)	/* Pointer to Container record. */
{
    Master *masterPtr = (Master *)clientData;
    Slave *slavePtr;
    Container *containerPtr = (Container *)clientData;
    Content *contentPtr;
    int x, y, width, height, tmp;
    int masterWidth, masterHeight, masterX, masterY;
    int containerWidth, containerHeight, containerX, containerY;
    double x1, y1, x2, y2;
    int abort;			/* May get set to non-zero to abort this
				 * placement operation. */

    masterPtr->flags &= ~PARENT_RECONFIG_PENDING;
    containerPtr->flags &= ~PARENT_RECONFIG_PENDING;

    /*
     * Abort any nested call to RecomputePlacement for this window, since
     * we'll do everything necessary here, and set up so this call can be
     * aborted if necessary.
     */

    if (masterPtr->abortPtr != NULL) {
	*masterPtr->abortPtr = 1;
    if (containerPtr->abortPtr != NULL) {
	*containerPtr->abortPtr = 1;
    }
    masterPtr->abortPtr = &abort;
    containerPtr->abortPtr = &abort;
    abort = 0;
    Tcl_Preserve(masterPtr);
    Tcl_Preserve(containerPtr);

    /*
     * Iterate over all the slaves for the master. Each slave's geometry can
     * be computed independently of the other slaves. Changes to the window's
     * Iterate over all the content windows for the container. Each content's geometry can
     * be computed independently of the other content. Changes to the window's
     * structure could cause almost anything to happen, including deleting the
     * parent or child. If this happens, we'll be told to abort.
     */

    for (slavePtr = masterPtr->slavePtr; slavePtr != NULL && !abort;
	    slavePtr = slavePtr->nextPtr) {
    for (contentPtr = containerPtr->contentPtr; contentPtr != NULL && !abort;
	    contentPtr = contentPtr->nextPtr) {
	/*
	 * Step 1: compute size and borderwidth of master, taking into account
	 * Step 1: compute size and borderwidth of container, taking into account
	 * desired border mode.
	 */

	masterX = masterY = 0;
	masterWidth = Tk_Width(masterPtr->tkwin);
	masterHeight = Tk_Height(masterPtr->tkwin);
	if (slavePtr->borderMode == BM_INSIDE) {
	    masterX = Tk_InternalBorderLeft(masterPtr->tkwin);
	    masterY = Tk_InternalBorderTop(masterPtr->tkwin);
	    masterWidth -= masterX + Tk_InternalBorderRight(masterPtr->tkwin);
	    masterHeight -= masterY +
		    Tk_InternalBorderBottom(masterPtr->tkwin);
	} else if (slavePtr->borderMode == BM_OUTSIDE) {
	    masterX = masterY = -Tk_Changes(masterPtr->tkwin)->border_width;
	    masterWidth -= 2 * masterX;
	    masterHeight -= 2 * masterY;
	containerX = containerY = 0;
	containerWidth = Tk_Width(containerPtr->tkwin);
	containerHeight = Tk_Height(containerPtr->tkwin);
	if (contentPtr->borderMode == BM_INSIDE) {
	    containerX = Tk_InternalBorderLeft(containerPtr->tkwin);
	    containerY = Tk_InternalBorderTop(containerPtr->tkwin);
	    containerWidth -= containerX + Tk_InternalBorderRight(containerPtr->tkwin);
	    containerHeight -= containerY +
		    Tk_InternalBorderBottom(containerPtr->tkwin);
	} else if (contentPtr->borderMode == BM_OUTSIDE) {
	    containerX = containerY = -Tk_Changes(containerPtr->tkwin)->border_width;
	    containerWidth -= 2 * containerX;
	    containerHeight -= 2 * containerY;
	}

	/*
	 * Step 2: compute size of slave (outside dimensions including border)
	 * and location of anchor point within master.
	 * Step 2: compute size of content (outside dimensions including border)
	 * and location of anchor point within container.
	 */

	x1 = slavePtr->x + masterX + (slavePtr->relX*masterWidth);
	x1 = contentPtr->x + containerX + (contentPtr->relX*containerWidth);
	x = (int) (x1 + ((x1 > 0) ? 0.5 : -0.5));
	y1 = slavePtr->y + masterY + (slavePtr->relY*masterHeight);
	y1 = contentPtr->y + containerY + (contentPtr->relY*containerHeight);
	y = (int) (y1 + ((y1 > 0) ? 0.5 : -0.5));
	if (slavePtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH)) {
	if (contentPtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH)) {
	    width = 0;
	    if (slavePtr->flags & CHILD_WIDTH) {
		width += slavePtr->width;
	    if (contentPtr->flags & CHILD_WIDTH) {
		width += contentPtr->width;
	    }
	    if (slavePtr->flags & CHILD_REL_WIDTH) {
	    if (contentPtr->flags & CHILD_REL_WIDTH) {
		/*
		 * The code below is a bit tricky. In order to round correctly
		 * when both relX and relWidth are specified, compute the
		 * location of the right edge and round that, then compute
		 * width. If we compute the width and round it, rounding
		 * errors in relX and relWidth accumulate.
		 */

		x2 = x1 + (slavePtr->relWidth*masterWidth);
		x2 = x1 + (contentPtr->relWidth*containerWidth);
		tmp = (int) (x2 + ((x2 > 0) ? 0.5 : -0.5));
		width += tmp - x;
	    }
	} else {
	    width = Tk_ReqWidth(slavePtr->tkwin)
		    + 2*Tk_Changes(slavePtr->tkwin)->border_width;
	    width = Tk_ReqWidth(contentPtr->tkwin)
		    + 2*Tk_Changes(contentPtr->tkwin)->border_width;
	}
	if (slavePtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT)) {
	if (contentPtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT)) {
	    height = 0;
	    if (slavePtr->flags & CHILD_HEIGHT) {
		height += slavePtr->height;
	    if (contentPtr->flags & CHILD_HEIGHT) {
		height += contentPtr->height;
	    }
	    if (slavePtr->flags & CHILD_REL_HEIGHT) {
	    if (contentPtr->flags & CHILD_REL_HEIGHT) {
		/*
		 * See note above for rounding errors in width computation.
		 */

		y2 = y1 + (slavePtr->relHeight*masterHeight);
		y2 = y1 + (contentPtr->relHeight*containerHeight);
		tmp = (int) (y2 + ((y2 > 0) ? 0.5 : -0.5));
		height += tmp - y;
	    }
	} else {
	    height = Tk_ReqHeight(slavePtr->tkwin)
		    + 2*Tk_Changes(slavePtr->tkwin)->border_width;
	    height = Tk_ReqHeight(contentPtr->tkwin)
		    + 2*Tk_Changes(contentPtr->tkwin)->border_width;
	}

	/*
	 * Step 3: adjust the x and y positions so that the desired anchor
	 * point on the slave appears at that position. Also adjust for the
	 * border mode and master's border.
	 * point on the content appears at that position. Also adjust for the
	 * border mode and container's border.
	 */

	switch (slavePtr->anchor) {
	switch (contentPtr->anchor) {
	case TK_ANCHOR_N:
	    x -= width/2;
	    break;
	case TK_ANCHOR_NE:
	    x -= width;
	    break;
	case TK_ANCHOR_E:
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
1018
1019
1020
1021
1022
1023
1024


1025
1026
1027
1028
1029
1030
1031
1032
1033
1034



1035
1036
1037
1038
1039
1040






1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052


1053
1054
1055
1056


1057
1058
1059
1060
1061


1062
1063
1064

1065
1066
1067
1068
1069
1070


1071
1072
1073
1074
1075
1076
1077

1078
1079
1080

1081
1082
1083
1084
1085
1086
1087

1088
1089
1090
1091
1092
1093


1094
1095
1096
1097
1098



1099
1100
1101
1102
1103
1104




1105
1106
1107
1108
1109
1110
1111





1112
1113
1114
1115
1116
1117




1118
1119
1120
1121
1122



1123
1124
1125
1126

1127
1128
1129
1130


1131
1132
1133
1134




1135
1136
1137
1138
1139
1140
1141
1142

1143
1144
1145
1146



1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157

1158
1159
1160

1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172


1173
1174
1175
1176
1177


1178
1179
1180
1181


1182
1183
1184



1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195

1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210


1211
1212
1213


1214
1215

1216


1217
1218
1219
1220
1221
1222
1223

1224
1225
1226


1227
1228
1229
1230



1231
1232
1233
1234
1235
1236
1237
1238
1239

1240
1241
1242

1243
1244
1245
1246
1247
1248

1249
1250
1251
1252
1253
1254


1255
1256
1257

1258
1259


1260
1261
1262


1263
1264
1265
1266


1267
1268
1269



1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281







-
-
+
+








-
-
-
+
+
+



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






-
-
+
+


-
-
+
+



-
-
+
+

-
+





-
-
+
+





-
+


-
+






-
+





-
-
+
+



-
-
-
+
+
+



-
-
-
-
+
+
+
+



-
-
-
-
-
+
+
+
+
+

-
-
-
-
+
+
+
+

-
-
-
+
+
+

-
+



-
-
+
+


-
-
-
-
+
+
+
+




-
+



-
-
-
+
+
+








-
+


-
+











-
-
+
+



-
-
+
+


-
-
+
+

-
-
-
+
+
+








-
+














-
-
+
+

-
-
+
+
-

-
-
+
+





-
+


-
-
+
+


-
-
-
+
+
+






-
+


-
+





-
+





-
-
+
+

-
+

-
-
+
+

-
-
+
+


-
-
+
+

-
-
-
+
+
+










	/*
	 * Step 4: adjust width and height again to reflect inside dimensions
	 * of window rather than outside. Also make sure that the width and
	 * height aren't zero.
	 */

	width -= 2*Tk_Changes(slavePtr->tkwin)->border_width;
	height -= 2*Tk_Changes(slavePtr->tkwin)->border_width;
	width -= 2*Tk_Changes(contentPtr->tkwin)->border_width;
	height -= 2*Tk_Changes(contentPtr->tkwin)->border_width;
	if (width <= 0) {
	    width = 1;
	}
	if (height <= 0) {
	    height = 1;
	}

	/*
	 * Step 5: reconfigure the window and map it if needed. If the slave
	 * is a child of the master, we do this ourselves. If the slave isn't
	 * a child of the master, let Tk_MaintainGeometry do the work (it will
	 * Step 5: reconfigure the window and map it if needed. If the content
	 * is a child of the container, we do this ourselves. If the content isn't
	 * a child of the container, let Tk_MaintainGeometry do the work (it will
	 * re-adjust things as relevant windows map, unmap, and move).
	 */

	if (masterPtr->tkwin == Tk_Parent(slavePtr->tkwin)) {
	    if ((x != Tk_X(slavePtr->tkwin))
		    || (y != Tk_Y(slavePtr->tkwin))
		    || (width != Tk_Width(slavePtr->tkwin))
		    || (height != Tk_Height(slavePtr->tkwin))) {
		Tk_MoveResizeWindow(slavePtr->tkwin, x, y, width, height);
	if (containerPtr->tkwin == Tk_Parent(contentPtr->tkwin)) {
	    if ((x != Tk_X(contentPtr->tkwin))
		    || (y != Tk_Y(contentPtr->tkwin))
		    || (width != Tk_Width(contentPtr->tkwin))
		    || (height != Tk_Height(contentPtr->tkwin))) {
		Tk_MoveResizeWindow(contentPtr->tkwin, x, y, width, height);
	    }
            if (abort) {
                break;
            }

	    /*
	     * Don't map the slave unless the master is mapped: the slave will
	     * get mapped later, when the master is mapped.
	     * Don't map the content unless the container is mapped: the content will
	     * get mapped later, when the container is mapped.
	     */

	    if (Tk_IsMapped(masterPtr->tkwin)) {
		Tk_MapWindow(slavePtr->tkwin);
	    if (Tk_IsMapped(containerPtr->tkwin)) {
		Tk_MapWindow(contentPtr->tkwin);
	    }
	} else {
	    if ((width <= 0) || (height <= 0)) {
		Tk_UnmaintainGeometry(slavePtr->tkwin, masterPtr->tkwin);
		Tk_UnmapWindow(slavePtr->tkwin);
		Tk_UnmaintainGeometry(contentPtr->tkwin, containerPtr->tkwin);
		Tk_UnmapWindow(contentPtr->tkwin);
	    } else {
		Tk_MaintainGeometry(slavePtr->tkwin, masterPtr->tkwin,
		Tk_MaintainGeometry(contentPtr->tkwin, containerPtr->tkwin,
			x, y, width, height);
	    }
	}
    }

    masterPtr->abortPtr = NULL;
    Tcl_Release(masterPtr);
    containerPtr->abortPtr = NULL;
    Tcl_Release(containerPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * MasterStructureProc --
 * PlaceStructureProc --
 *
 *	This function is invoked by the Tk event handler when StructureNotify
 *	events occur for a master window.
 *	events occur for a container window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Structures get cleaned up if the window was deleted. If the window was
 *	resized then slave geometries get recomputed.
 *	resized then content geometries get recomputed.
 *
 *----------------------------------------------------------------------
 */

static void
MasterStructureProc(
    ClientData clientData,	/* Pointer to Master structure for window
PlaceStructureProc(
    ClientData clientData,	/* Pointer to Container structure for window
				 * referred to by eventPtr. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    Master *masterPtr = (Master *)clientData;
    Slave *slavePtr, *nextPtr;
    TkDisplay *dispPtr = ((TkWindow *) masterPtr->tkwin)->dispPtr;
    Container *containerPtr = (Container *)clientData;
    Content *contentPtr, *nextPtr;
    TkDisplay *dispPtr = ((TkWindow *) containerPtr->tkwin)->dispPtr;

    switch (eventPtr->type) {
    case ConfigureNotify:
	if ((masterPtr->slavePtr != NULL)
		&& !(masterPtr->flags & PARENT_RECONFIG_PENDING)) {
	    masterPtr->flags |= PARENT_RECONFIG_PENDING;
	    Tcl_DoWhenIdle(RecomputePlacement, masterPtr);
	if ((containerPtr->contentPtr != NULL)
		&& !(containerPtr->flags & PARENT_RECONFIG_PENDING)) {
	    containerPtr->flags |= PARENT_RECONFIG_PENDING;
	    Tcl_DoWhenIdle(RecomputePlacement, containerPtr);
	}
	return;
    case DestroyNotify:
	for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
		slavePtr = nextPtr) {
	    slavePtr->masterPtr = NULL;
	    nextPtr = slavePtr->nextPtr;
	    slavePtr->nextPtr = NULL;
	for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
		contentPtr = nextPtr) {
	    contentPtr->containerPtr = NULL;
	    nextPtr = contentPtr->nextPtr;
	    contentPtr->nextPtr = NULL;
	}
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->masterTable,
		masterPtr->tkwin));
	if (masterPtr->flags & PARENT_RECONFIG_PENDING) {
	    Tcl_CancelIdleCall(RecomputePlacement, masterPtr);
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->containerTable,
		containerPtr->tkwin));
	if (containerPtr->flags & PARENT_RECONFIG_PENDING) {
	    Tcl_CancelIdleCall(RecomputePlacement, containerPtr);
	}
	masterPtr->tkwin = NULL;
	if (masterPtr->abortPtr != NULL) {
	    *masterPtr->abortPtr = 1;
	containerPtr->tkwin = NULL;
	if (containerPtr->abortPtr != NULL) {
	    *containerPtr->abortPtr = 1;
	}
	Tcl_EventuallyFree(masterPtr, TCL_DYNAMIC);
	Tcl_EventuallyFree(containerPtr, TCL_DYNAMIC);
	return;
    case MapNotify:
	/*
	 * When a master gets mapped, must redo the geometry computation so
	 * that all of its slaves get remapped.
	 * When a container gets mapped, must redo the geometry computation so
	 * that all of its content get remapped.
	 */

	if ((masterPtr->slavePtr != NULL)
		&& !(masterPtr->flags & PARENT_RECONFIG_PENDING)) {
	    masterPtr->flags |= PARENT_RECONFIG_PENDING;
	    Tcl_DoWhenIdle(RecomputePlacement, masterPtr);
	if ((containerPtr->contentPtr != NULL)
		&& !(containerPtr->flags & PARENT_RECONFIG_PENDING)) {
	    containerPtr->flags |= PARENT_RECONFIG_PENDING;
	    Tcl_DoWhenIdle(RecomputePlacement, containerPtr);
	}
	return;
    case UnmapNotify:
	/*
	 * Unmap all of the slaves when the master gets unmapped, so that they
	 * Unmap all of the content when the container gets unmapped, so that they
	 * don't keep redisplaying themselves.
	 */

	for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
		slavePtr = slavePtr->nextPtr) {
	    Tk_UnmapWindow(slavePtr->tkwin);
	for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
		contentPtr = contentPtr->nextPtr) {
	    Tk_UnmapWindow(contentPtr->tkwin);
	}
	return;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveStructureProc --
 * ContentStructureProc --
 *
 *	This function is invoked by the Tk event handler when StructureNotify
 *	events occur for a slave window.
 *	events occur for a content window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Structures get cleaned up if the window was deleted.
 *
 *----------------------------------------------------------------------
 */

static void
SlaveStructureProc(
    ClientData clientData,	/* Pointer to Slave structure for window
ContentStructureProc(
    ClientData clientData,	/* Pointer to Content structure for window
				 * referred to by eventPtr. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    Slave *slavePtr = (Slave *)clientData;
    TkDisplay *dispPtr = ((TkWindow *) slavePtr->tkwin)->dispPtr;
    Content *contentPtr = (Content *)clientData;
    TkDisplay *dispPtr = ((TkWindow *) contentPtr->tkwin)->dispPtr;

    if (eventPtr->type == DestroyNotify) {
	if (slavePtr->masterPtr != NULL) {
	    UnlinkSlave(slavePtr);
	if (contentPtr->containerPtr != NULL) {
	    UnlinkContent(contentPtr);
	}
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable,
		slavePtr->tkwin));
	FreeSlave(slavePtr);
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->contentTable,
		contentPtr->tkwin));
	FreeContent(contentPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * PlaceRequestProc --
 *
 *	This function is invoked by Tk whenever a slave managed by us changes
 *	This function is invoked by Tk whenever a content managed by us changes
 *	its requested geometry.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The window will get relayed out, if its requested size has anything to
 *	do with its actual size.
 *
 *----------------------------------------------------------------------
 */

static void
PlaceRequestProc(
    ClientData clientData,	/* Pointer to our record for slave. */
    Tk_Window tkwin)		/* Window that changed its desired size. */
    ClientData clientData,	/* Pointer to our record for content. */
    TCL_UNUSED(Tk_Window))		/* Window that changed its desired size. */
{
    Slave *slavePtr = (Slave *)clientData;
    Master *masterPtr;
    Content *contentPtr = (Content *)clientData;
    Container *containerPtr;
    (void)tkwin;

    if ((slavePtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH))
	    && (slavePtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT))) {
    if ((contentPtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH))
	    && (contentPtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT))) {
        /*
         * Send a ConfigureNotify to indicate that the size change
         * request was rejected.
         */

        TkDoConfigureNotify((TkWindow *)(slavePtr->tkwin));
        TkDoConfigureNotify((TkWindow *)(contentPtr->tkwin));
	return;
    }
    masterPtr = slavePtr->masterPtr;
    if (masterPtr == NULL) {
    containerPtr = contentPtr->containerPtr;
    if (containerPtr == NULL) {
	return;
    }
    if (!(masterPtr->flags & PARENT_RECONFIG_PENDING)) {
	masterPtr->flags |= PARENT_RECONFIG_PENDING;
	Tcl_DoWhenIdle(RecomputePlacement, masterPtr);
    if (!(containerPtr->flags & PARENT_RECONFIG_PENDING)) {
	containerPtr->flags |= PARENT_RECONFIG_PENDING;
	Tcl_DoWhenIdle(RecomputePlacement, containerPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * PlaceLostSlaveProc --
 * PlaceLostContentProc --
 *
 *	This function is invoked by Tk whenever some other geometry claims
 *	control over a slave that used to be managed by us.
 *	control over a content window that used to be managed by us.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Forgets all placer-related information about the slave.
 *	Forgets all placer-related information about the content window.
 *
 *--------------------------------------------------------------
 */

static void
PlaceLostSlaveProc(
    ClientData clientData,	/* Slave structure for slave window that was
PlaceLostContentProc(
    ClientData clientData,	/* Content structure for content window that was
				 * stolen away. */
    Tk_Window tkwin)		/* Tk's handle for the slave window. */
    Tk_Window tkwin)		/* Tk's handle for the content window. */
{
    Slave *slavePtr = (Slave *)clientData;
    TkDisplay *dispPtr = ((TkWindow *) slavePtr->tkwin)->dispPtr;
    Content *contentPtr = (Content *)clientData;
    TkDisplay *dispPtr = ((TkWindow *) contentPtr->tkwin)->dispPtr;

    if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) {
	Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin);
    if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
	Tk_UnmaintainGeometry(contentPtr->tkwin, contentPtr->containerPtr->tkwin);
    }
    Tk_UnmapWindow(tkwin);
    UnlinkSlave(slavePtr);
    Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable,
    UnlinkContent(contentPtr);
    Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->contentTable,
	    tkwin));
    Tk_DeleteEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc,
	    slavePtr);
    FreeSlave(slavePtr);
    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
125

126
127
128
129
130
131
132
133
134






135
136
137
138
139
140
141
50
51
52
53
54
55
56

57







58


59


60

61
62
63

64
65
66
67

68

69
70
71
72
73
74
75

76





77

78
79


80
81


82

83

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




101
102
103
104
105

106
107

108
109
110
111






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







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



-
+



-
+
-







-
+
-
-
-
-
-

-
+

-
-
+
+
-
-
+
-

-
+
















-
-
-
-
+
+
+
+

-
+

-
+



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







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 */
/* 0 */
/* Slot 0 is reserved */
EXTERN void		Tk_MacOSXSetEmbedHandler(
				Tk_MacOSXEmbedRegisterWinProc *registerWinProcPtr,
				Tk_MacOSXEmbedGetGrafPortProc *getPortProcPtr,
				Tk_MacOSXEmbedMakeContainerExistProc *containerExistProcPtr,
				Tk_MacOSXEmbedGetClipProc *getClipProc,
				Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc);
/* 1 */
/* Slot 1 is reserved */
EXTERN void		Tk_MacOSXTurnOffMenus(void);
/* 2 */
/* Slot 2 is reserved */
EXTERN void		Tk_MacOSXTkOwnsCursor(int tkOwnsIt);
/* 3 */
/* Slot 3 is reserved */
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);
/* 7 */
/* Slot 7 is reserved */
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 void		Tk_MacOSXSetEmbedHandler_(
EXTERN Tk_Window	Tk_MacOSXGetTkWindow(void *w);
				Tk_MacOSXEmbedRegisterWinProc *registerWinProcPtr,
				Tk_MacOSXEmbedGetGrafPortProc *getPortProcPtr,
				Tk_MacOSXEmbedMakeContainerExistProc *containerExistProcPtr,
				Tk_MacOSXEmbedGetClipProc *getClipProc,
				Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc);
/* 12 */
EXTERN void		Tk_MacOSXTurnOffMenus_(void);
EXTERN void *		Tk_MacOSXGetCGContextForDrawable(Drawable drawable);
/* 13 */
EXTERN void		Tk_MacOSXTkOwnsCursor_(int tkOwnsIt);
/* 14 */
EXTERN void *		Tk_MacOSXGetNSWindowForDrawable(Drawable drawable);
/* Slot 14 is reserved */
EXTERN void		TkMacOSXInitMenus_(Tcl_Interp *interp);
/* 15 */
/* Slot 15 is reserved */
EXTERN void		TkMacOSXInitAppleEvents_(Tcl_Interp *interp);
/* 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 (*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 (*reserved0)(void);
    void (*reserved1)(void);
    void (*reserved2)(void);
    void (*reserved3)(void);
    void (*tkMacOSXInitAppleEvents) (Tcl_Interp *interp); /* 4 */
    void (*tkGenWMConfigureEvent) (Tk_Window tkwin, int x, int y, int width, int height, int flags); /* 5 */
    void (*tkGenWMConfigureEvent_) (Tk_Window tkwin, int x, int y, int width, int height, int flags); /* 5 */
    void (*tkMacOSXInvalClipRgns) (Tk_Window tkwin); /* 6 */
    void * (*tkMacOSXGetDrawablePort) (Drawable drawable); /* 7 */
    void (*reserved7)(void);
    void * (*tkMacOSXGetRootControl) (Drawable drawable); /* 8 */
    void (*tk_MacOSXSetupTkNotifier) (void); /* 9 */
    int (*tk_MacOSXIsAppInFront) (void); /* 10 */
    void (*tk_MacOSXSetEmbedHandler_) (Tk_MacOSXEmbedRegisterWinProc *registerWinProcPtr, Tk_MacOSXEmbedGetGrafPortProc *getPortProcPtr, Tk_MacOSXEmbedMakeContainerExistProc *containerExistProcPtr, Tk_MacOSXEmbedGetClipProc *getClipProc, Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc); /* 11 */
    void (*tk_MacOSXTurnOffMenus_) (void); /* 12 */
    void (*tk_MacOSXTkOwnsCursor_) (int tkOwnsIt); /* 13 */
    void (*tkMacOSXInitMenus_) (Tcl_Interp *interp); /* 14 */
    void (*tkMacOSXInitAppleEvents_) (Tcl_Interp *interp); /* 15 */
    void (*tkGenWMConfigureEvent_) (Tk_Window tkwin, int x, int y, int width, int height, int flags); /* 16 */
    Tk_Window (*tk_MacOSXGetTkWindow) (void *w); /* 11 */
    void * (*tk_MacOSXGetCGContextForDrawable) (Drawable drawable); /* 12 */
    void * (*tk_MacOSXGetNSWindowForDrawable) (Drawable drawable); /* 13 */
    void (*reserved14)(void);
    void (*reserved15)(void);
    void (*tkGenWMConfigureEvent) (Tk_Window tkwin, int x, int y, int width, int height, int flags); /* 16 */
#endif /* AQUA */
} TkPlatStubs;

extern const TkPlatStubs *tkPlatStubsPtr;

#ifdef __cplusplus
}
158
159
160
161
162
163
164
165
166
167
168




169
170
171
172
173
174
175
176


177
178
179
180

181
182
183
184
185
186
187
188
189
190
191
192
193
194








195
196
197
198


199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218



219
141
142
143
144
145
146
147




148
149
150
151




152
153


154
155
156
157


158
159
160
161
162
163
164








165
166
167
168
169
170
171
172




173
174
175
176
177
178
179
180







181
182
183
184
185
186
187
188
189
190
191







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


-
-
+
+


-
-
+






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






-
-
-
-
-
-
-







+
+
+

	(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 */
#define Tk_MacOSXSetEmbedHandler \
	(tkPlatStubsPtr->tk_MacOSXSetEmbedHandler) /* 0 */
#define Tk_MacOSXTurnOffMenus \
	(tkPlatStubsPtr->tk_MacOSXTurnOffMenus) /* 1 */
/* Slot 0 is reserved */
/* Slot 1 is reserved */
/* Slot 2 is reserved */
/* Slot 3 is reserved */
#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 */
#define TkMacOSXGetDrawablePort \
	(tkPlatStubsPtr->tkMacOSXGetDrawablePort) /* 7 */
/* Slot 7 is reserved */
#define TkMacOSXGetRootControl \
	(tkPlatStubsPtr->tkMacOSXGetRootControl) /* 8 */
#define Tk_MacOSXSetupTkNotifier \
	(tkPlatStubsPtr->tk_MacOSXSetupTkNotifier) /* 9 */
#define Tk_MacOSXIsAppInFront \
	(tkPlatStubsPtr->tk_MacOSXIsAppInFront) /* 10 */
#define Tk_MacOSXSetEmbedHandler_ \
	(tkPlatStubsPtr->tk_MacOSXSetEmbedHandler_) /* 11 */
#define Tk_MacOSXTurnOffMenus_ \
	(tkPlatStubsPtr->tk_MacOSXTurnOffMenus_) /* 12 */
#define Tk_MacOSXTkOwnsCursor_ \
	(tkPlatStubsPtr->tk_MacOSXTkOwnsCursor_) /* 13 */
#define TkMacOSXInitMenus_ \
	(tkPlatStubsPtr->tkMacOSXInitMenus_) /* 14 */
#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 TkMacOSXInitAppleEvents_ \
	(tkPlatStubsPtr->tkMacOSXInitAppleEvents_) /* 15 */
#define TkGenWMConfigureEvent_ \
	(tkPlatStubsPtr->tkGenWMConfigureEvent_) /* 16 */
#define TkGenWMConfigureEvent \
	(tkPlatStubsPtr->tkGenWMConfigureEvent) /* 16 */
#endif /* AQUA */

#endif /* defined(USE_TK_STUBS) */

/* !END!: Do not edit above this line. */

#undef Tk_MacOSXSetEmbedHandler_
#undef Tk_MacOSXTurnOffMenus_
#undef Tk_MacOSXTkOwnsCursor_
#undef TkMacOSXInitMenus_
#undef TkMacOSXInitAppleEvents_
#undef TkGenWMConfigureEvent_

#ifdef __cplusplus
}
#endif

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#undef TkGenWMConfigureEvent_
#define Tk_MacOSXGetNSViewForDrawable TkMacOSXGetRootControl

#endif /* _TKPLATDECLS */

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








-
+


















-
+







/*
 * 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 © 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"
#endif

typedef struct {
    TkWindow *grabWinPtr;	/* Window that defines the top of the grab
				 * tree in a global grab. */
    int lastState;		/* Last known state flags. */
    unsigned lastState;		/* Last known state flags. */
    XPoint lastPos;		/* Last reported mouse position. */
    TkWindow *lastWinPtr;	/* Last reported mouse window. */
    TkWindow *restrictWinPtr;	/* Window to which all mouse events will be
				 * reported. */
    TkWindow *cursorWinPtr;	/* Window that is currently controlling the
				 * global cursor. */
} ThreadSpecificData;
220
221
222
223
224
225
226
227
228



229
230
231
232
233
234
235
220
221
222
223
224
225
226


227
228
229
230
231
232
233
234
235
236







-
-
+
+
+







{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    TkWindow *winPtr = (TkWindow *)tkwin;
    TkWindow *targetWinPtr;
    XPoint pos;
    XEvent event;
    int changes = (state ^ tsdPtr->lastState) & ALL_BUTTONS;
    int type, b, mask;
    unsigned changes = (state ^ tsdPtr->lastState) & ALL_BUTTONS;
    int type, b;
    unsigned mask;

    pos.x = x;
    pos.y = y;

    /*
     * Use the current keyboard state, but the old mouse button state since we
     * haven't generated the button events yet.
250
251
252
253
254
255
256
257

258
259
260
261
262
263
264
251
252
253
254
255
256
257

258
259
260
261
262
263
264
265







-
+








    /*
     * 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 = TkGetButtonMask(b);
	mask = Tk_GetButtonMask(b);
	if (changes & mask) {
	    if (state & mask) {
		type = ButtonPress;

		/*
		 * ButtonPress - Set restrict window if we aren't grabbed, or
		 * if this is the first button down.

Changes to generic/tkRectOval.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





-
-
+
+







/*
 * tkRectOval.c --
 *
 *	This file implements rectangle and oval items for canvas widgets.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1991-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkCanvas.h"

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
1
2
3
4
5
6
7
8
9
10
11



12
13
14
15
16
17
18
19
20
21











-
-
-
+
+
+







/*
 * 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 © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1998-2000 Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkScale.h"
353
354
355
356
357
358
359
360

361
362
363
364
365
366
367
353
354
355
356
357
358
359

360
361
362
363
364
365
366
367







-
+








    /*
     * The widget was just created, no command callback must be invoked.
     */

    scalePtr->flags &= ~INVOKE_COMMAND;

    Tcl_SetObjResult(interp, TkNewWindowObj(scalePtr->tkwin));
    Tcl_SetObjResult(interp, Tk_NewWindowObj(scalePtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ScaleWidgetObjCmd --
655
656
657
658
659
660
661
662
663
664
665




666
667
668
669
670
671
672
673
674
675
655
656
657
658
659
660
661




662
663
664
665
666


667
668
669
670
671
672
673







-
-
-
-
+
+
+
+

-
-







		    TCL_GLOBAL_ONLY);
	    if ((valuePtr != NULL) &&
		    (Tcl_GetDoubleFromObj(NULL, valuePtr, &value) == TCL_OK)) {
		scalePtr->value = TkRoundValueToResolution(scalePtr, value);
	    }
	}

	/*
	 * Several options need special processing, such as parsing the
	 * orientation and creating GCs.
	 */
        /*
         * The fromValue shall not be rounded to the resolution, but the
         * toValue and tickInterval do.
         */

	scalePtr->fromValue = TkRoundValueToResolution(scalePtr,
		scalePtr->fromValue);
	scalePtr->toValue = TkRoundValueToResolution(scalePtr, scalePtr->toValue);
	scalePtr->tickInterval = TkRoundIntervalToResolution(scalePtr,
		scalePtr->tickInterval);

	/*
	 * Make sure that the tick interval has the right sign so that
	 * addition moves from fromValue to toValue.

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 © 1996 Sun Microsystems, Inc.
 * Copyright © 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

Changes to generic/tkScrollbar.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







-
-
+
+







/*
 * tkScrollbar.c --
 *
 *	This module implements a scrollbar widgets for the Tk toolkit. A
 *	scrollbar displays a slider and two arrows; mouse clicks on features
 *	within the scrollbar cause scrolling commands to be invoked.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkScrollbar.h"
192
193
194
195
196
197
198
199

200
201
202
203
204
205
206
192
193
194
195
196
197
198

199
200
201
202
203
204
205
206







-
+







    scrollPtr->flags = 0;

    if (ConfigureScrollbar(interp, scrollPtr, objc-2, objv+2, 0) != TCL_OK) {
	Tk_DestroyWindow(scrollPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, TkNewWindowObj(scrollPtr->tkwin));
    Tcl_SetObjResult(interp, Tk_NewWindowObj(scrollPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ScrollbarWidgetObjCmd --
222
223
224
225
226
227
228
229
230


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


229
230
231
232
233
234
235
236
237







-
-
+
+







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;
    TkSizeT length;
    int result = TCL_OK, cmdIndex, length;
    TkSizeT len;
    static const char *const commandNames[] = {
        "activate", "cget", "configure", "delta", "fraction",
        "get", "identify", "set", NULL
    };
    enum command {
        COMMAND_ACTIVATE, COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DELTA,
        COMMAND_FRACTION, COMMAND_GET, COMMAND_IDENTIFY, COMMAND_SET
267
268
269
270
271
272
273
274

275
276
277
278
279
280

281
282
283
284
285
286
287
267
268
269
270
271
272
273

274
275
276
277
278
279

280
281
282
283
284
285
286
287







-
+





-
+







	    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], &length)[0];
	c = Tcl_GetStringFromObj(objv[2], &len)[0];
	oldActiveField = scrollPtr->activeField;
	if ((c == 'a') && (strcmp(Tcl_GetString(objv[2]), "arrow1") == 0)) {
	    scrollPtr->activeField = TOP_ARROW;
	} else if ((c == 'a') && (strcmp(Tcl_GetString(objv[2]), "arrow2") == 0)) {
	    scrollPtr->activeField = BOTTOM_ARROW;
	} else if ((c == 's') && (strncmp(Tcl_GetString(objv[2]), "slider", length) == 0)) {
	} else if ((c == 's') && (strncmp(Tcl_GetString(objv[2]), "slider", len) == 0)) {
	    scrollPtr->activeField = SLIDER;
	} else {
	    scrollPtr->activeField = OUTSIDE;
	}
	if (oldActiveField != scrollPtr->activeField) {
	    TkScrollbarEventuallyRedraw(scrollPtr);
	}
306
307
308
309
310
311
312
313

314
315
316
317
318
319
320
306
307
308
309
310
311
312

313
314
315
316
317
318
319
320







-
+







	} else {
	    result = ConfigureScrollbar(interp, scrollPtr, objc-2,
		    objv+2, TK_CONFIG_ARGV_ONLY);
	}
	break;
    }
    case COMMAND_DELTA: {
	int xDelta, yDelta, pixels, length;
	int xDelta, yDelta, pixels;
	double fraction;

	if (objc != 4) {
		Tcl_WrongNumArgs(interp, 1, objv, "delta xDelta yDelta");
	    goto error;
	}
	if ((Tcl_GetIntFromObj(interp, objv[2], &xDelta) != TCL_OK)
335
336
337
338
339
340
341
342

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

342
343
344
345
346
347
348
349







-
+







	} else {
	    fraction = ((double) pixels / (double) length);
	}
	Tcl_SetObjResult(interp, Tcl_NewDoubleObj(fraction));
	break;
    }
    case COMMAND_FRACTION: {
	int x, y, pos, length;
	int x, y, pos;
	double fraction;

	if (objc != 4) {
		Tcl_WrongNumArgs(interp, 1, objv, "fraction x y");
	    goto error;
	}
	if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)

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

Changes to generic/tkSelect.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






-
-
+
+







/*
 * tkSelect.c --
 *
 *	This file manages the selection for the Tk toolkit, translating
 *	between the standard X ICCCM conventions and Tcl commands.
 *
 * Copyright (c) 1990-1993 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1990-1993 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkSelect.h"
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







-
+







    Tcl_Interp *interp;		/* Interpreter in which to invoke command. */
    int cmdLength;		/* # of non-NULL bytes in command. */
    int charOffset;		/* The offset of the next char to retrieve. */
    int byteOffset;		/* The expected byte offset of the next
				 * chunk. */
    char buffer[4];		/* A buffer to hold part of a UTF character
				 * that is split across chunks. */
    char command[1];		/* Command to invoke. Actual space is
    char command[TKFLEXARRAY];		/* Command to invoke. Actual space is
				 * allocated as large as necessary. This must
				 * be the last entry in the structure. */
} CommandInfo;

/*
 * When selection ownership is claimed with the "selection own" Tcl command,
 * one of the following structures is created to record the Tcl command to be
896
897
898
899
900
901
902
903

904
905
906
907
908
909
910
896
897
898
899
900
901
902

903
904
905
906
907
908
909
910







-
+







	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)
		    + 1 + cmdLength);
	    cmdInfoPtr->interp = interp;
	    cmdInfoPtr->charOffset = 0;
988
989
990
991
992
993
994
995

996
997
998
999
1000
1001
1002
988
989
990
991
992
993
994

995
996
997
998
999
1000
1001
1002







-
+








	    /*
	     * Ignore the internal clipboard window.
	     */

	    if ((infoPtr != NULL)
		    && (infoPtr->owner != winPtr->dispPtr->clipWindow)) {
		Tcl_SetObjResult(interp, TkNewWindowObj(infoPtr->owner));
		Tcl_SetObjResult(interp, Tk_NewWindowObj(infoPtr->owner));
	    }
	    return TCL_OK;
	}

	tkwin = Tk_NameToWindow(interp, Tcl_GetString(objs[0]), tkwin);
	if (tkwin == NULL) {
	    return TCL_ERROR;
1285
1286
1287
1288
1289
1290
1291
1292

1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1285
1286
1287
1288
1289
1290
1291

1292
1293
1294
1295


1296
1297
1298
1299
1300
1301
1302







-
+



-
-







 *--------------------------------------------------------------
 */

static int
SelGetProc(
    ClientData clientData,	/* Dynamic string holding partially assembled
				 * selection. */
    Tcl_Interp *dummy,		/* Interpreter used for error reporting (not
    TCL_UNUSED(Tcl_Interp *),	/* Interpreter used for error reporting (not
				 * used). */
    const char *portion)	/* New information to be appended. */
{
    (void)dummy;

    Tcl_DStringAppend((Tcl_DString *)clientData, portion, -1);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *

Changes to generic/tkSelect.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






-
+







/*
 * tkSelect.h --
 *
 *	Declarations of types shared among the files that implement selection
 *	support.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 * Copyright © 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.
 */

#ifndef _TKSELECT
#define _TKSELECT

Changes to generic/tkSquare.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









-
+







/*
 * tkSquare.c --
 *
 *	This module implements "square" widgets that are object based. A
 *	"square" is a widget that displays a single square that can be moved
 *	around and resized. This file is intended as an example of how to
 *	build a widget; it isn't included in the normal wish, but it is
 *	included in "tktest".
 *
 * Copyright (c) 1997 Sun Microsystems, Inc.
 * Copyright © 1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#if 0
#define __NO_OLD_CONFIG
230
231
232
233
234
235
236
237

238
239
240
241
242
243
244
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244







-
+







    enum {
	SQUARE_CGET, SQUARE_CONFIGURE
    };
    Tcl_Obj *resultObjPtr;
    int index;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg...?");
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], squareOptions,
	    sizeof(char *), "command", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }

Changes to generic/tkStubInit.c.

1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

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

46
47
48
49
50
51
52
53
54
55
56
57
58
59






60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

104
105
106
107
108
109







110
111
112
113
114
115
116
1
2
3
4
5

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82





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





100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122





-
+




















+



















+














+
+
+
+
+
+















-
-
-
-
-

















-
-
-
-
-


+






+
+
+
+
+
+
+







/*
 * tkStubInit.c --
 *
 *	This file contains the initializers for the Tk stub vectors.
 *
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 * Copyright © 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"

#if !(defined(_WIN32) || defined(MAC_OSX_TK))
/* UNIX */
#define UNIX_TK
#include "tkUnixInt.h"
#endif

#ifdef _WIN32
#include "tkWinInt.h"
#endif

#if defined(MAC_OSX_TK)
/* we could have used _TKMACINT */
#include "tkMacOSXInt.h"
#include "tkMacOSXPrivate.h"
#endif

/* TODO: These ought to come in some other way */
#include "tkPlatDecls.h"
#include "tkIntXlibDecls.h"

MODULE_SCOPE const TkStubs tkStubs;

/*
 * Remove macro that might interfere with the definition below.
 */

#undef Tk_MainEx
#undef Tk_FreeXId
#undef Tk_FreeStyleFromObj
#undef Tk_GetStyleFromObj
#undef TkWinGetPlatformId
#undef TkPutImage
#undef XPutImage
#define TkMacOSXSetUpClippingRgn (void (*)(Drawable))(void *)doNothing

#if defined(_WIN32) && !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
#   define Tk_TranslateWinEvent TkTranslateWinEvent
#   define Tk_PointerEvent TkWinPointerEvent
#define TkWinGetPlatformId winGetPlatformId
static int TkWinGetPlatformId(void) {
    return 2;
}
#else
#   define Tk_TranslateWinEvent 0
#   define Tk_PointerEvent 0
#   define TkWinGetPlatformId 0
#endif

static int
doNothing(void)
{
    /* dummy implementation, no need to do anything */
    return 0;
}

#if defined(TK_NO_DEPRECATED) || TCL_MAJOR_VERSION > 8
#define Tk_MainEx 0
#define Tk_FreeXId 0
#define Tk_FreeStyleFromObj 0
#define Tk_GetStyleFromObj 0
#define TkWinGetPlatformId 0
#define Tk_PhotoPutBlock_NoComposite 0
#define Tk_PhotoPutZoomedBlock_NoComposite 0
#define Tk_PhotoExpand_Panic 0
#define Tk_PhotoPutBlock_Panic 0
#define Tk_PhotoPutZoomedBlock_Panic 0
#define Tk_PhotoSetSize_Panic 0
#define Tk_CreateOldPhotoImageFormat 0
#else
static void
doNothing(void)
{
    /* dummy implementation, no need to do anything */
}
#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 Tk_MacOSXSetEmbedHandler_ Tk_MacOSXSetEmbedHandler
#define Tk_MacOSXTurnOffMenus_ Tk_MacOSXTurnOffMenus
#define Tk_MacOSXTkOwnsCursor_ Tk_MacOSXTkOwnsCursor
#define TkMacOSXInitMenus_ TkMacOSXInitMenus
#define TkMacOSXInitAppleEvents_ TkMacOSXInitAppleEvents
#define TkGenWMConfigureEvent_ TkGenWMConfigureEvent
#define TkGenerateActivateEvents_ TkGenerateActivateEvents
#define TkMacOSXDrawable Tk_MacOSXGetNSWindowForDrawable
#define Tk_CanvasTagsParseProc \
		(int (*) (void *, Tcl_Interp *,Tk_Window, const char *, char *, \
		int offset))(void *)TkCanvasTagsParseProc
#define Tk_CanvasTagsPrintProc \
		(const char *(*) (void *,Tk_Window, char *, int, \
		Tcl_FreeProc **))(void *)TkCanvasTagsPrintProc

#if !defined(MAC_OSX_TK) && defined(MAC_OSX_TCL)
#   undef TkpWillDrawWidget
#   undef TkpRedrawWidget
#   define TkpWillDrawWidget ((int (*)(Tk_Window))(void *)doNothing)
#   define TkpRedrawWidget ((void (*)(Tk_Window))(void *)doNothing)
#endif

#ifdef _WIN32

int
TkpCmapStressed(Tk_Window tkwin, Colormap colormap)
{
    (void)tkwin;
491
492
493
494
495
496
497

498
499









500
501

502
503
504
505

506
507

508
509
510
511

512
513

514
515
516
517
518
519
520
521
522
523
524
525
497
498
499
500
501
502
503
504


505
506
507
508
509
510
511
512
513
514

515
516
517
518

519


520




521


522





523
524
525
526
527
528
529







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

-
+



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







    TkOrientPrintProc, /* 178 */
    TkSmoothParseProc, /* 179 */
    TkSmoothPrintProc, /* 180 */
    TkDrawAngledTextLayout, /* 181 */
    TkUnderlineAngledTextLayout, /* 182 */
    TkIntersectAngledTextLayout, /* 183 */
    TkDrawAngledChars, /* 184 */
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
    TkDebugPhotoStringMatchDef, /* 185 */
#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
    0, /* 185 */
#endif /* UNIX */
#if defined(_WIN32) /* WIN */
    0, /* 185 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
    TkpRedrawWidget, /* 185 */
#endif /* MACOSX */
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
    0, /* 186 */
#endif /* X11 */
#endif /* UNIX */
#if defined(_WIN32) /* WIN */
    0, /* 186 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
#ifdef MAC_OSX_TCL /* MACOSX */
    0, /* 186 */ /* Dummy entry for stubs table backwards compatibility */
    TkpRedrawWidget, /* 186 */
    TkpWillDrawWidget, /* 186 */
#endif /* AQUA */
#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
    0, /* 187 */
#endif /* X11 */
#endif /* MACOSX */
#if defined(_WIN32) /* WIN */
    0, /* 187 */
    TkDebugPhotoStringMatchDef, /* 187 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    0, /* 187 */ /* Dummy entry for stubs table backwards compatibility */
    TkpWillDrawWidget, /* 187 */
#endif /* AQUA */
};

static const TkIntPlatStubs tkIntPlatStubs = {
    TCL_STUB_MAGIC,
    0,
#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
    TkAlignImageData, /* 0 */
579
580
581
582
583
584
585
586

587
588
589
590
591
592
593
594
595
596
597
598
599
600
601

602
603
604
605
606
607
608

609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624

625
626
627
628
629
630
631
583
584
585
586
587
588
589

590
591
592
593
594
595
596
597
598
599
600
601
602
603
604

605
606
607
608
609
610
611

612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627

628
629
630
631
632
633
634
635







-
+














-
+






-
+















-
+







    TkpSetCapture, /* 4 */
    TkpSetCursor, /* 5 */
    TkpWmSetState, /* 6 */
    TkAboutDlg, /* 7 */
    TkMacOSXButtonKeyState, /* 8 */
    TkMacOSXClearMenubarActive, /* 9 */
    TkMacOSXDispatchMenuEvent, /* 10 */
    TkMacOSXInstallCursor, /* 11 */
    0, /* 11 */
    TkMacOSXHandleTearoffMenu, /* 12 */
    0, /* 13 */
    TkMacOSXDoHLEvent, /* 14 */
    0, /* 15 */
    TkMacOSXGetXWindow, /* 16 */
    TkMacOSXGrowToplevel, /* 17 */
    TkMacOSXHandleMenuSelect, /* 18 */
    0, /* 19 */
    0, /* 20 */
    TkMacOSXInvalidateWindow, /* 21 */
    TkMacOSXIsCharacterMissing, /* 22 */
    TkMacOSXMakeRealWindowExist, /* 23 */
    TkMacOSXMakeStippleMap, /* 24 */
    TkMacOSXMenuClick, /* 25 */
    TkMacOSXRegisterOffScreenWindow, /* 26 */
    0, /* 26 */
    TkMacOSXResizable, /* 27 */
    TkMacOSXSetHelpMenuItemCount, /* 28 */
    TkMacOSXSetScrollbarGrow, /* 29 */
    TkMacOSXSetUpClippingRgn, /* 30 */
    TkMacOSXSetUpGraphicsPort, /* 31 */
    TkMacOSXUpdateClipRgn, /* 32 */
    TkMacOSXUnregisterMacWindow, /* 33 */
    0, /* 33 */
    TkMacOSXUseMenuID, /* 34 */
    TkMacOSXVisableClipRgn, /* 35 */
    TkMacOSXWinBounds, /* 36 */
    TkMacOSXWindowOffset, /* 37 */
    TkSetMacColor, /* 38 */
    TkSetWMName, /* 39 */
    0, /* 40 */
    TkMacOSXZoomToplevel, /* 41 */
    Tk_TopCoordsToWindow, /* 42 */
    TkMacOSXContainerId, /* 43 */
    TkMacOSXGetHostToplevel, /* 44 */
    TkMacOSXPreprocessMenu, /* 45 */
    TkpIsWindowFloating, /* 46 */
    TkpGetCapture, /* 47 */
    0, /* 48 */
    TkGetTransientMaster, /* 49 */
    TkMacOSXGetContainer, /* 49 */
    TkGenerateButtonEvent, /* 50 */
    TkGenWMDestroyEvent, /* 51 */
    TkMacOSXSetDrawingEnabled, /* 52 */
    TkpGetMS, /* 53 */
    TkMacOSXDrawable, /* 54 */
    TkpScanWindowId, /* 55 */
#endif /* AQUA */
946
947
948
949
950
951
952
953

954
955
956
957
958
959
960
950
951
952
953
954
955
956

957
958
959
960
961
962
963
964







-
+







    XSetCommand, /* 99 */
    XWindowEvent, /* 100 */
    XGetWindowAttributes, /* 101 */
    XGetWMColormapWindows, /* 102 */
    XIconifyWindow, /* 103 */
    XWithdrawWindow, /* 104 */
    XListHosts, /* 105 */
    0, /* 106 */
    XSetClipRectangles, /* 106 */
    XFlush, /* 107 */
    XGrabServer, /* 108 */
    XUngrabServer, /* 109 */
    XFree, /* 110 */
    XNoOp, /* 111 */
    XSynchronize, /* 112 */
    XLookupColor, /* 113 */
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
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







-
-
-
-
+
+
+
+

-
+

-
+



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







    Tk_GetHINSTANCE, /* 1 */
    Tk_GetHWND, /* 2 */
    Tk_HWNDToWindow, /* 3 */
    Tk_PointerEvent, /* 4 */
    Tk_TranslateWinEvent, /* 5 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    Tk_MacOSXSetEmbedHandler, /* 0 */
    Tk_MacOSXTurnOffMenus, /* 1 */
    Tk_MacOSXTkOwnsCursor, /* 2 */
    TkMacOSXInitMenus, /* 3 */
    0, /* 0 */
    0, /* 1 */
    0, /* 2 */
    0, /* 3 */
    TkMacOSXInitAppleEvents, /* 4 */
    TkGenWMConfigureEvent, /* 5 */
    TkGenWMConfigureEvent_, /* 5 */
    TkMacOSXInvalClipRgns, /* 6 */
    TkMacOSXGetDrawablePort, /* 7 */
    0, /* 7 */
    TkMacOSXGetRootControl, /* 8 */
    Tk_MacOSXSetupTkNotifier, /* 9 */
    Tk_MacOSXIsAppInFront, /* 10 */
    Tk_MacOSXSetEmbedHandler_, /* 11 */
    Tk_MacOSXTurnOffMenus_, /* 12 */
    Tk_MacOSXTkOwnsCursor_, /* 13 */
    TkMacOSXInitMenus_, /* 14 */
    TkMacOSXInitAppleEvents_, /* 15 */
    TkGenWMConfigureEvent_, /* 16 */
    Tk_MacOSXGetTkWindow, /* 11 */
    Tk_MacOSXGetCGContextForDrawable, /* 12 */
    Tk_MacOSXGetNSWindowForDrawable, /* 13 */
    0, /* 14 */
    0, /* 15 */
    TkGenWMConfigureEvent, /* 16 */
#endif /* AQUA */
};

static const TkStubHooks tkStubHooks = {
    &tkPlatStubs,
    &tkIntStubs,
    &tkIntPlatStubs,
1142
1143
1144
1145
1146
1147
1148
1149

1150
1151
1152
1153
1154
1155
1156
1146
1147
1148
1149
1150
1151
1152

1153
1154
1155
1156
1157
1158
1159
1160







-
+







    Tk_GetCursor, /* 91 */
    Tk_GetCursorFromData, /* 92 */
    Tk_GetFont, /* 93 */
    Tk_GetFontFromObj, /* 94 */
    Tk_GetFontMetrics, /* 95 */
    Tk_GetGC, /* 96 */
    Tk_GetImage, /* 97 */
    Tk_GetImageMasterData, /* 98 */
    Tk_GetImageModelData, /* 98 */
    Tk_GetItemTypes, /* 99 */
    Tk_GetJoinStyle, /* 100 */
    Tk_GetJustify, /* 101 */
    Tk_GetNumMainWindows, /* 102 */
    Tk_GetOption, /* 103 */
    Tk_GetPixels, /* 104 */
    Tk_GetPixmap, /* 105 */
1318
1319
1320
1321
1322
1323
1324






1325

1326
1327
1328
1329
1330
1331
1332
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334

1335
1336
1337
1338
1339
1340
1341
1342







+
+
+
+
+
+
-
+







    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 */
    Tk_CreatePhotoImageFormatVersion3 /* 274 */
    Tk_CreatePhotoImageFormatVersion3 /* 280 */
};

/* !END!: Do not edit above this line. */


#ifdef __CYGWIN__
void *Tk_GetHINSTANCE(void)

Changes to generic/tkStubLib.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






-
-
+
+







/*
 * 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 Paul Duffin.
 * Copyright © 1998-1999 Scriptics Corporation.
 * Copyright © 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"

71
72
73
74
75
76
77
78

79
80
81
82
83
84
85




86


87
88
89
90
91
92
93
71
72
73
74
75
76
77

78
79
80
81
82

83
84
85
86
87
88

89
90
91
92
93
94
95
96
97







-
+




-


+
+
+
+
-
+
+







#undef Tk_InitStubs
MODULE_SCOPE const char *
Tk_InitStubs(
    Tcl_Interp *interp,
    const char *version,
    int exact)
{
    const char *packageName = "Tk";
    const char *packageName = "tk";
    const char *errMsg = NULL;
    void *clientData = NULL;
    const char *actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp,
	    packageName, version, 0, &clientData);
    const TkStubs *stubsPtr = (const TkStubs *)clientData;

    if (actualVersion == NULL) {
	packageName = "Tk";
	actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp,
    	    packageName, version, 0, &clientData);
	if (actualVersion == NULL) {
	return NULL;
	    return NULL;
	}
    }

    if (exact) {
	const char *p = version;
	int count = 0;

	while (*p) {
109
110
111
112
113
114
115
116

117
118
119
120
121
122
123
124






125
126
127
128
129
130
131
113
114
115
116
117
118
119

120
121
122






123
124
125
126
127
128
129
130
131
132
133
134
135







-
+


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







	    actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp, packageName,
		    version, 1, NULL);
	    if (actualVersion == NULL) {
		return NULL;
	    }
	}
    }
    if (stubsPtr == NULL) {
    if (clientData == NULL) {
	errMsg = "missing stub table pointer";
    } else {
	tkStubsPtr = stubsPtr;
	if (stubsPtr->hooks) {
	    tkPlatStubsPtr = stubsPtr->hooks->tkPlatStubs;
	    tkIntStubsPtr = stubsPtr->hooks->tkIntStubs;
	    tkIntPlatStubsPtr = stubsPtr->hooks->tkIntPlatStubs;
	    tkIntXlibStubsPtr = stubsPtr->hooks->tkIntXlibStubs;
	tkStubsPtr = (const TkStubs *)clientData;
	if (tkStubsPtr->hooks) {
	    tkPlatStubsPtr = tkStubsPtr->hooks->tkPlatStubs;
	    tkIntStubsPtr = tkStubsPtr->hooks->tkIntStubs;
	    tkIntPlatStubsPtr = tkStubsPtr->hooks->tkIntPlatStubs;
	    tkIntXlibStubsPtr = tkStubsPtr->hooks->tkIntXlibStubs;
	} else {
	    tkPlatStubsPtr = NULL;
	    tkIntStubsPtr = NULL;
	    tkIntPlatStubsPtr = NULL;
	    tkIntXlibStubsPtr = NULL;
	}
	return actualVersion;

Changes to generic/tkStyle.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





-
-
+
+







/*
 * tkStyle.c --
 *
 *	This file implements the widget styles and themes support.
 *
 * Copyright (c) 1990-1993 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1990-1993 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

174
175
176
177
178
179
180
181

182
183
184
185
186
187
188
189
190
191
192
174
175
176
177
178
179
180

181
182
183
184

185
186
187
188
189
190
191







-
+



-







 *	Memory allocated.
 *
 *---------------------------------------------------------------------------
 */

void
TkStylePkgInit(
    TkMainInfo *mainPtr)	/* The application being created. */
    TCL_UNUSED(TkMainInfo *))	/* The application being created. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)mainPtr;

    if (tsdPtr->nbInit != 0) {
	return;
    }

    /*
     * Initialize tables.
230
231
232
233
234
235
236
237

238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
229
230
231
232
233
234
235

236
237
238
239
240
241
242
243

244
245
246
247
248
249
250







-
+







-







 *	Memory freed.
 *
 *---------------------------------------------------------------------------
 */

void
TkStylePkgFree(
    TkMainInfo *mainPtr)	/* The application being deleted. */
    TCL_UNUSED(TkMainInfo *))	/* The application being deleted. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    Tcl_HashSearch search;
    Tcl_HashEntry *entryPtr;
    StyleEngine *enginePtr;
    int i;
    (void)mainPtr;

    tsdPtr->nbInit--;
    if (tsdPtr->nbInit != 0) {
	return;
    }

    /*
519
520
521
522
523
524
525
526

527
528
529
530
531
532
533
534
535
536
517
518
519
520
521
522
523

524
525


526
527
528
529
530
531
532







-
+

-
-







 *	Memory freed.
 *
 *---------------------------------------------------------------------------
 */

static void
FreeElement(
    Element *elementPtr)	/* The element to free. */
    TCL_UNUSED(Element *))	/* The element to free. */
{
    (void)elementPtr;

    /* Nothing to do. */
}

/*
 *---------------------------------------------------------------------------
 *
 * InitStyledElement --
1376
1377
1378
1379
1380
1381
1382
1383

1384
1385
1386
1387
1388
1389
1390
1391
1392
1372
1373
1374
1375
1376
1377
1378

1379
1380

1381
1382
1383
1384
1385
1386
1387







-
+

-







 *	No-op. Present only for stubs compatibility.
 *
 *---------------------------------------------------------------------------
 */

void
Tk_FreeStyle(
    Tk_Style style)
    TCL_UNUSED(Tk_Style))
{
    (void)style;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_AllocStyleFromObj --
 *

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 © 1993-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 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
27
28
29
30
31
32
33
34

35
36

37
38
39
40
41
42
43
27
28
29
30
31
32
33

34
35

36
37
38
39
40
41
42
43







-
+

-
+







#ifdef _WIN32
#include "tkWinInt.h"
#endif

#if defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#include "tkScrollbar.h"
#define LOG_DISPLAY TkTestLogDisplay()
#define LOG_DISPLAY(drawable) TkTestLogDisplay(drawable)
#else
#define LOG_DISPLAY 1
#define LOG_DISPLAY(drawable) 1
#endif

#ifdef __UNIX__
#include "tkUnixInt.h"
#endif

/*
53
54
55
56
57
58
59
60

61
62
63
64


65
66
67
68
69
70

71
72
73
74
75
76
77
78

79
80


81
82
83
84
85
86
87
88
89

90
91
92
93
94
95
96
53
54
55
56
57
58
59

60
61
62


63
64
65
66
67
68
69

70
71
72
73
74
75
76
77

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

91
92
93
94
95
96
97
98







-
+


-
-
+
+





-
+







-
+


+
+








-
+







#endif
EXTERN int		Tktest_Init(Tcl_Interp *interp);
#ifdef __cplusplus
}
#endif

/*
 * The following data structure represents the master for a test image:
 * The following data structure represents the model for a test image:
 */

typedef struct TImageMaster {
    Tk_ImageMaster master;	/* Tk's token for image master. */
typedef struct TImageModel {
    Tk_ImageModel model;	/* Tk's token for image model. */
    Tcl_Interp *interp;		/* Interpreter for application. */
    int width, height;		/* Dimensions of image. */
    char *imageName;		/* Name of image (malloc-ed). */
    char *varName;		/* Name of variable in which to log events for
				 * image (malloc-ed). */
} TImageMaster;
} TImageModel;

/*
 * The following data structure represents a particular use of a particular
 * test image.
 */

typedef struct TImageInstance {
    TImageMaster *masterPtr;	/* Pointer to master for image. */
    TImageModel *modelPtr;	/* Pointer to model for image. */
    XColor *fg;			/* Foreground color for drawing in image. */
    GC gc;			/* Graphics context for drawing in image. */
    Bool displayFailed;         /* macOS display attempted out of drawRect. */
    char buffer[200 + TCL_INTEGER_SPACE * 6]; /* message to log on display. */
} TImageInstance;

/*
 * The type record for test images:
 */

static int		ImageCreate(Tcl_Interp *interp,
			    const char *name, int argc, Tcl_Obj *const objv[],
			    const Tk_ImageType *typePtr, Tk_ImageMaster master,
			    const Tk_ImageType *typePtr, Tk_ImageModel model,
			    ClientData *clientDataPtr);
static ClientData	ImageGet(Tk_Window tkwin, ClientData clientData);
static void		ImageDisplay(ClientData clientData,
			    Display *display, Drawable drawable,
			    int imageX, int imageY, int width,
			    int height, int drawableX,
			    int drawableY);
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







-
+







	return TCL_ERROR;
    }

    /*
     * Create additional commands for testing Tk.
     */

    if (Tcl_PkgProvideEx(interp, "Tktest", TK_PATCH_LEVEL, NULL) == TCL_ERROR) {
    if (Tcl_PkgProvideEx(interp, "tk::test", TK_PATCH_LEVEL, NULL) == TCL_ERROR) {
	return TCL_ERROR;
    }

    Tcl_CreateObjCommand(interp, "square", SquareObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "testbitmap", TestbitmapObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testborder", TestborderObjCmd,
328
329
330
331
332
333
334
335

336
337
338
339
340
341
342
343
344
345
346
347
348
330
331
332
333
334
335
336

337
338
339
340
341


342
343
344
345
346
347
348







-
+




-
-







 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestbitmapObjCmd(
    ClientData clientData,	/* 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 objects. */
{
    (void)clientData;

    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;
363
364
365
366
367
368
369
370

371
372
373
374
375
376
377
378
379
380
381
382
383
363
364
365
366
367
368
369

370
371
372
373
374


375
376
377
378
379
380
381







-
+




-
-







 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestborderObjCmd(
    ClientData clientData,	/* Main window for application. */
    TCL_UNUSED(ClientData),	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    (void)clientData;

    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;
398
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413
414
415
416
417
418
396
397
398
399
400
401
402

403
404
405
406
407


408
409
410
411
412
413
414







-
+




-
-







 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestcolorObjCmd(
    ClientData clientData,	/* 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 objects. */
{
    (void)clientData;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "color");
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, TkDebugColor(Tk_MainWindow(interp),
	    Tcl_GetString(objv[1])));
    return TCL_OK;
433
434
435
436
437
438
439
440

441
442
443
444
445
446
447
448
449
450
451
452
453
429
430
431
432
433
434
435

436
437
438
439
440


441
442
443
444
445
446
447







-
+




-
-







 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestcursorObjCmd(
    ClientData clientData,	/* 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 objects. */
{
    (void)clientData;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "cursor");
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, TkDebugCursor(Tk_MainWindow(interp),
	    Tcl_GetString(objv[1])));
    return TCL_OK;
469
470
471
472
473
474
475
476
477
478
479




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




470
471
472
473
474
475




476
477
478
479
480
481
482







-
-
-
-
+
+
+
+


-
-
-
-







 *	deleted.
 *
 *----------------------------------------------------------------------
 */

static int
TestdeleteappsObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
    TCL_UNUSED(void *),	/* Main window for application. */
    TCL_UNUSED(Tcl_Interp *),		/* Current interpreter. */
    TCL_UNUSED(int),			/* Number of arguments. */
    TCL_UNUSED(Tcl_Obj *const *))		/* Argument strings. */
{
    NewApp *nextPtr;
    (void)clientData;
    (void)interp;
    (void)objc;
    (void)objv;

    while (newAppPtr != NULL) {
	nextPtr = newAppPtr->nextPtr;
	Tcl_DeleteInterp(newAppPtr->interp);
	ckfree(newAppPtr);
	newAppPtr = nextPtr;
    }
544
545
546
547
548
549
550
551

552
553
554
555
556
557
558
534
535
536
537
538
539
540

541
542
543
544
545
546
547
548







-
+







    int index, result = TCL_OK;

    /*
     * Structures used by the "chain1" subcommand and also shared by the
     * "chain2" subcommand:
     */

    typedef struct ExtensionWidgetRecord {
    typedef struct {
	TrivialCommandHeader header;
	Tcl_Obj *base1ObjPtr;
	Tcl_Obj *base2ObjPtr;
	Tcl_Obj *extension3ObjPtr;
	Tcl_Obj *extension4ObjPtr;
	Tcl_Obj *extension5ObjPtr;
    } ExtensionWidgetRecord;
572
573
574
575
576
577
578
579

580
581
582
583
584
585
586
562
563
564
565
566
567
568

569
570
571
572
573
574
575
576







-
+







    if (Tcl_GetIndexFromObjStruct(interp, objv[1], options,
	    sizeof(char *), "command", 0, &index)!= TCL_OK) {
	return TCL_ERROR;
    }

    switch (index) {
    case ALL_TYPES: {
	typedef struct TypesRecord {
	typedef struct {
	    TrivialCommandHeader header;
	    Tcl_Obj *booleanPtr;
	    Tcl_Obj *integerPtr;
	    Tcl_Obj *doublePtr;
	    Tcl_Obj *stringPtr;
	    Tcl_Obj *stringTablePtr;
	    Tcl_Obj *colorPtr;
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
635
636
637
638
639
640
641

642
643
644
645
646
647
648







-







		"", offsetof(TypesRecord, customPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, &CustomOption, 0x4000},
	    {TK_OPTION_SYNONYM, "-synonym", NULL, NULL,
		NULL, 0, TCL_INDEX_NONE, 0, "-color", 0x8000},
	    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
	};
	Tk_OptionTable optionTable;
	Tk_Window tkwin;

	optionTable = Tk_CreateOptionTable(interp, typesSpecs);
	tables[index] = optionTable;
	tkwin = Tk_CreateWindowFromPath(interp, (Tk_Window)clientData,
		Tcl_GetString(objv[2]), NULL);
	if (tkwin == NULL) {
	    return TCL_ERROR;
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
690
691
692
693
694
695
696

697
698
699
700
701
702
703







-







	    Tcl_SetObjResult(interp, objv[2]);
	}
	break;
    }

    case CHAIN1: {
	ExtensionWidgetRecord *recordPtr;
	Tk_Window tkwin;
	Tk_OptionTable optionTable;

	tkwin = Tk_CreateWindowFromPath(interp, (Tk_Window)clientData,
		Tcl_GetString(objv[2]), NULL);
	if (tkwin == NULL) {
	    return TCL_ERROR;
	}
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
742
743
744
745
746
747
748

749
750
751
752
753
754
755







-







		offsetof(ExtensionWidgetRecord, base2ObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
	    {TK_OPTION_STRING,
		"-oneAgain", "oneAgain", "OneAgain", "one again",
		offsetof(ExtensionWidgetRecord, extension5ObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
	    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0,
		(ClientData) baseSpecs, 0}
	};
	Tk_Window tkwin;
	Tk_OptionTable optionTable;

	tkwin = Tk_CreateWindowFromPath(interp, (Tk_Window)clientData,
		Tcl_GetString(objv[2]), NULL);
	if (tkwin == NULL) {
	    return TCL_ERROR;
	}
793
794
795
796
797
798
799
800

801
802
803
804
805
806
807
780
781
782
783
784
785
786

787
788
789
790
791
792
793
794







-
+







		    TrivialEventProc, (ClientData) recordPtr);
	    Tcl_SetObjResult(interp, objv[2]);
	}
	break;
    }

    case CONFIG_ERROR: {
	typedef struct ErrorWidgetRecord {
	typedef struct {
	    Tcl_Obj *intPtr;
	} ErrorWidgetRecord;
	ErrorWidgetRecord widgetRecord;
	static const Tk_OptionSpec errorSpecs[] = {
	    {TK_OPTION_INT, "-int", "integer", "Integer", "bogus",
		offsetof(ErrorWidgetRecord, intPtr), 0, 0, NULL, 0},
	    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
847
848
849
850
851
852
853
854

855
856
857
858
859
860
861
834
835
836
837
838
839
840

841
842
843
844
845
846
847
848







-
+







    case INTERNAL: {
	/*
	 * This command is similar to the "alltypes" command except that it
	 * stores all the configuration options as internal forms instead of
	 * objects.
	 */

	typedef struct InternalRecord {
	typedef struct {
	    TrivialCommandHeader header;
	    int boolean;
	    int integer;
	    double doubleValue;
	    char *string;
	    int index;
	    XColor *colorPtr;
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
910
911
912
913
914
915
916

917
918
919
920
921
922
923







-







		TCL_INDEX_NONE, offsetof(InternalRecord, custom),
		TK_CONFIG_NULL_OK, &CustomOption, 0x4000},
	    {TK_OPTION_SYNONYM, "-synonym", NULL, NULL,
		NULL, TCL_INDEX_NONE, TCL_INDEX_NONE, 0, "-color", 0x8000},
	    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
	};
	Tk_OptionTable optionTable;
	Tk_Window tkwin;

	optionTable = Tk_CreateOptionTable(interp, internalSpecs);
	tables[index] = optionTable;
	tkwin = Tk_CreateWindowFromPath(interp, (Tk_Window)clientData,
		Tcl_GetString(objv[2]), NULL);
	if (tkwin == NULL) {
	    return TCL_ERROR;
979
980
981
982
983
984
985
986

987
988
989
990
991
992
993
965
966
967
968
969
970
971

972
973
974
975
976
977
978
979







-
+







	if (result == TCL_OK) {
	    Tcl_SetObjResult(interp, objv[2]);
	}
	break;
    }

    case NEW: {
	typedef struct FiveRecord {
	typedef struct {
	    TrivialCommandHeader header;
	    Tcl_Obj *one;
	    Tcl_Obj *two;
	    Tcl_Obj *three;
	    Tcl_Obj *four;
	    Tcl_Obj *five;
	} FiveRecord;
1038
1039
1040
1041
1042
1043
1044
1045

1046
1047
1048
1049
1050
1051
1052
1024
1025
1026
1027
1028
1029
1030

1031
1032
1033
1034
1035
1036
1037
1038







-
+







	if (result != TCL_OK) {
	    ckfree(recordPtr);
	}

	break;
    }
    case NOT_ENOUGH_PARAMS: {
	typedef struct NotEnoughRecord {
	typedef struct {
	    Tcl_Obj *fooObjPtr;
	} NotEnoughRecord;
	NotEnoughRecord record;
	static const Tk_OptionSpec errorSpecs[] = {
	    {TK_OPTION_INT, "-foo", "foo", "Foo", "0",
		offsetof(NotEnoughRecord, fooObjPtr), 0, 0, NULL, 0},
	    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
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
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







-
+


-
-
-
+
+
+

-
+


-
+







-
+


-
+







	Tcl_DecrRefCount(newObjPtr);
	Tk_FreeConfigOptions( (char *) &record, optionTable, tkwin);
	Tk_DestroyWindow(tkwin);
	return result;
    }

    case TWO_WINDOWS: {
	typedef struct SlaveRecord {
	typedef struct {
	    TrivialCommandHeader header;
	    Tcl_Obj *windowPtr;
	} SlaveRecord;
	SlaveRecord *recordPtr;
	static const Tk_OptionSpec slaveSpecs[] = {
	} ContentRecord;
	ContentRecord *recordPtr;
	static const Tk_OptionSpec contentSpecs[] = {
	    {TK_OPTION_WINDOW, "-window", "window", "Window", ".bar",
		offsetof(SlaveRecord, windowPtr), TCL_INDEX_NONE, TK_CONFIG_NULL_OK, NULL, 0},
		offsetof(ContentRecord, windowPtr), TCL_INDEX_NONE, TK_CONFIG_NULL_OK, NULL, 0},
	    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
	};
	Tk_Window tkwin = Tk_CreateWindowFromPath(interp,
	tkwin = Tk_CreateWindowFromPath(interp,
		(Tk_Window)clientData, Tcl_GetString(objv[2]), NULL);

	if (tkwin == NULL) {
	    return TCL_ERROR;
	}
	Tk_SetClass(tkwin, "Test");

	recordPtr = (SlaveRecord *)ckalloc(sizeof(SlaveRecord));
	recordPtr = (ContentRecord *)ckalloc(sizeof(ContentRecord));
	recordPtr->header.interp = interp;
	recordPtr->header.optionTable = Tk_CreateOptionTable(interp,
		slaveSpecs);
		contentSpecs);
	tables[index] = recordPtr->header.optionTable;
	recordPtr->header.tkwin = tkwin;
	recordPtr->windowPtr = NULL;

	result = Tk_InitOptions(interp, recordPtr,
		recordPtr->header.optionTable, tkwin);
	if (result == TCL_OK) {
1160
1161
1162
1163
1164
1165
1166
1167

1168
1169
1170
1171
1172
1173
1174
1146
1147
1148
1149
1150
1151
1152

1153
1154
1155
1156
1157
1158
1159
1160







-
+







    Tcl_Obj *resultObjPtr;
    int index, mask;
    TrivialCommandHeader *headerPtr = (TrivialCommandHeader *)clientData;
    Tk_Window tkwin = headerPtr->tkwin;
    Tk_SavedOptions saved;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg...?");
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], options,
	    sizeof(char *), "command", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
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
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







-
-
+
+




-
+


-
















-
-
+
+









-
+







ImageCreate(
    Tcl_Interp *interp,		/* Interpreter for application containing
				 * image. */
    const char *name,			/* Name to use for image. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument strings for options (doesn't
				 * include image name or type). */
    const Tk_ImageType *typePtr,	/* Pointer to our type record (not used). */
    Tk_ImageMaster master,	/* Token for image, to be used by us in later
    TCL_UNUSED(const Tk_ImageType *),	/* Pointer to our type record (not used). */
	Tk_ImageModel model,	/* Token for image, to be used by us in later
				 * callbacks. */
    ClientData *clientDataPtr)	/* Store manager's token for image here; it
				 * will be returned in later callbacks. */
{
    TImageMaster *timPtr;
    TImageModel *timPtr;
    const char *varName;
    int i;
    (void)typePtr;

    varName = "log";
    for (i = 0; i < objc; i += 2) {
	if (strcmp(Tcl_GetString(objv[i]), "-variable") != 0) {
	    Tcl_AppendResult(interp, "bad option name \"",
		    Tcl_GetString(objv[i]), "\"", NULL);
	    return TCL_ERROR;
	}
	if ((i+1) == objc) {
	    Tcl_AppendResult(interp, "no value given for \"",
		    Tcl_GetString(objv[i]), "\" option", NULL);
	    return TCL_ERROR;
	}
	varName = Tcl_GetString(objv[i+1]);
    }

    timPtr = (TImageMaster *)ckalloc(sizeof(TImageMaster));
    timPtr->master = master;
    timPtr = (TImageModel *)ckalloc(sizeof(TImageModel));
    timPtr->model = model;
    timPtr->interp = interp;
    timPtr->width = 30;
    timPtr->height = 15;
    timPtr->imageName = (char *)ckalloc(strlen(name) + 1);
    strcpy(timPtr->imageName, name);
    timPtr->varName = (char *)ckalloc(strlen(varName) + 1);
    strcpy(timPtr->varName, varName);
    Tcl_CreateObjCommand(interp, name, ImageObjCmd, timPtr, NULL);
    *clientDataPtr = timPtr;
    Tk_ImageChanged(master, 0, 0, 30, 15, 30, 15);
    Tk_ImageChanged(model, 0, 0, 30, 15, 30, 15);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ImageObjCmd --
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
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







-
+




















-
+







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. */
{
    TImageMaster *timPtr = (TImageMaster *)clientData;
    TImageModel *timPtr = (TImageModel *)clientData;
    int x, y, width, height;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    if (strcmp(Tcl_GetString(objv[1]), "changed") == 0) {
	if (objc != 8) {
		Tcl_WrongNumArgs(interp, 1, objv, "changed x y width height"
			" imageWidth imageHeight");
	    return TCL_ERROR;
	}
	if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &width) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &height) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &timPtr->width) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[7], &timPtr->height) != TCL_OK)) {
	    return TCL_ERROR;
	}
	Tk_ImageChanged(timPtr->master, x, y, width, height, timPtr->width,
	Tk_ImageChanged(timPtr->model, x, y, width, height, timPtr->width,
		timPtr->height);
    } else {
	Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]),
		"\": must be changed", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
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
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







-
+

-
+









-
+



+







 *----------------------------------------------------------------------
 */

static ClientData
ImageGet(
    Tk_Window tkwin,		/* Token for window in which image will be
				 * used. */
    ClientData clientData)	/* Pointer to TImageMaster for image. */
    ClientData clientData)	/* Pointer to TImageModel for image. */
{
    TImageMaster *timPtr = (TImageMaster *)clientData;
    TImageModel *timPtr = (TImageModel *)clientData;
    TImageInstance *instPtr;
    char buffer[100];
    XGCValues gcValues;

    sprintf(buffer, "%s get", timPtr->imageName);
    Tcl_SetVar2(timPtr->interp, timPtr->varName, NULL, buffer,
	    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);

    instPtr = (TImageInstance *)ckalloc(sizeof(TImageInstance));
    instPtr->masterPtr = timPtr;
    instPtr->modelPtr = timPtr;
    instPtr->fg = Tk_GetColor(timPtr->interp, tkwin, "#ff0000");
    gcValues.foreground = instPtr->fg->pixel;
    instPtr->gc = Tk_GetGC(tkwin, GCForeground, &gcValues);
    instPtr->displayFailed = False;
    return instPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * ImageDisplay --
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
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







-



-
-
-
+
+
+

-
+
-
-

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


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

-
-
+
+







				 * origin of image. */
    int width, int height,	/* Dimensions of area to redraw. */
    int drawableX, int drawableY)
				/* Coordinates in drawable corresponding to
				 * imageX and imageY. */
{
    TImageInstance *instPtr = (TImageInstance *)clientData;
    char buffer[200 + TCL_INTEGER_SPACE * 6];

    /*
     * The purpose of the test image type is to track the calls to an image
     * display proc and record the parameters passed in each call.  On macOS
     * a display proc must be run inside of the drawRect method of an NSView
     * in order for the graphics operations to have any effect.  To deal with
     * display proc and record the parameters passed in each call.  On macOS a
     * display proc must be run inside of the drawRect method of an NSView in
     * order for the graphics operations to have any effect.  To deal with
     * this, whenever a display proc is called outside of any drawRect method
     * it schedules a redraw of the NSView by calling [view setNeedsDisplay:YES].
     * it schedules a redraw of the NSView.
     * This will trigger a later call to the view's drawRect method which will
     * run the display proc a second time.
     *
     * This complicates testing, since it can result in more calls to the display
     * proc than are expected by the test.  It can also result in an inconsistent
     * number of calls unless the test waits until the call to drawRect actually
     * occurs before validating its results.
     *
     * In an attempt to work around this, this display proc only logs those
     * In an attempt to work around this, each image instance maintains it own
     * calls which occur within a drawRect method.  This means that tests must
     * be written so as to ensure that the drawRect method is run before
     * copy of the log message which gets written on the first call to the
     * results are validated.  In practice it usually suffices to run update
     * idletasks (to run the display proc the first time) followed by update
     * (to run the display proc in drawRect).
     * display proc.  This usually means that the message created on macOS is
     *
     * This also has the consequence that the image changed command will log
     * different results on Aqua than on other systems, because when the image
     * the same as that created on other platforms.  However it is possible
     * is redisplayed in the drawRect method the entire image will be drawn,
     * not just the changed portion.  Tests must account for this.
     * for the messages to differ for other reasons, namely differences in
     * how damage regions are computed.
     */

    if (LOG_DISPLAY) {
	sprintf(buffer, "%s display %d %d %d %d",
		instPtr->masterPtr->imageName, imageX, imageY, width, height);
	Tcl_SetVar2(instPtr->masterPtr->interp, instPtr->masterPtr->varName,
		    NULL, buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
    }
    if (width > (instPtr->masterPtr->width - imageX)) {
	width = instPtr->masterPtr->width - imageX;
    if (LOG_DISPLAY(drawable)) {
	if (instPtr->displayFailed == False) {

	    /*
	     * Drawing is possible on the first call to DisplayImage.
	     * Log the message.
	     */

	    sprintf(instPtr->buffer, "%s display %d %d %d %d",
	    instPtr->modelPtr->imageName, imageX, imageY, width, height);
	}
	Tcl_SetVar2(instPtr->modelPtr->interp, instPtr->modelPtr->varName,
		    NULL, instPtr->buffer,
		    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
	instPtr->displayFailed = False;
    } else {

	/*
         * Drawing is not possible on the first call to DisplayImage.
	 * Save the message, but do not log it until the actual display.
	 */

	if (instPtr->displayFailed == False) {
	    sprintf(instPtr->buffer, "%s display %d %d %d %d",
		    instPtr->modelPtr->imageName, imageX, imageY, width, height);
	}
	instPtr->displayFailed = True;
    }
    if (width > (instPtr->modelPtr->width - imageX)) {
	width = instPtr->modelPtr->width - imageX;
    }
    if (height > (instPtr->masterPtr->height - imageY)) {
	height = instPtr->masterPtr->height - imageY;
    if (height > (instPtr->modelPtr->height - imageY)) {
	height = instPtr->modelPtr->height - imageY;
    }

    XDrawRectangle(display, drawable, instPtr->gc, drawableX, drawableY,
	    (unsigned) (width-1), (unsigned) (height-1));
    XDrawLine(display, drawable, instPtr->gc, drawableX, drawableY,
	    (int) (drawableX + width - 1), (int) (drawableY + height - 1));
    XDrawLine(display, drawable, instPtr->gc, drawableX,
1633
1634
1635
1636
1637
1638
1639
1640
1641


1642
1643
1644
1645
1646
1647
1648
1628
1629
1630
1631
1632
1633
1634


1635
1636
1637
1638
1639
1640
1641
1642
1643







-
-
+
+







ImageFree(
    ClientData clientData,	/* Pointer to TImageInstance for instance. */
    Display *display)		/* Display where image was to be drawn. */
{
    TImageInstance *instPtr = (TImageInstance *)clientData;
    char buffer[200];

    sprintf(buffer, "%s free", instPtr->masterPtr->imageName);
    Tcl_SetVar2(instPtr->masterPtr->interp, instPtr->masterPtr->varName, NULL,
    sprintf(buffer, "%s free", instPtr->modelPtr->imageName);
    Tcl_SetVar2(instPtr->modelPtr->interp, instPtr->modelPtr->varName, NULL,
	    buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
    Tk_FreeColor(instPtr->fg);
    Tk_FreeGC(display, instPtr->gc);
    ckfree(instPtr);
}

/*
1660
1661
1662
1663
1664
1665
1666
1667

1668
1669
1670
1671

1672
1673
1674
1675
1676
1677
1678
1655
1656
1657
1658
1659
1660
1661

1662
1663
1664
1665

1666
1667
1668
1669
1670
1671
1672
1673







-
+



-
+







 *	Information about the image is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ImageDelete(
    ClientData clientData)	/* Pointer to TImageMaster for image. When
    ClientData clientData)	/* Pointer to TImageModel for image. When
				 * this function is called, no more instances
				 * exist. */
{
    TImageMaster *timPtr = (TImageMaster *)clientData;
    TImageModel *timPtr = (TImageModel *)clientData;
    char buffer[100];

    sprintf(buffer, "%s delete", timPtr->imageName);
    Tcl_SetVar2(timPtr->interp, timPtr->varName, NULL, buffer,
	    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);

    Tcl_DeleteCommand(timPtr->interp, timPtr->imageName);
1804
1805
1806
1807
1808
1809
1810
1811

1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1799
1800
1801
1802
1803
1804
1805

1806
1807
1808
1809
1810
1811
1812

1813
1814
1815
1816
1817
1818
1819







-
+






-







 *
 *----------------------------------------------------------------------
 */

#if defined(_WIN32)
static int
TestmetricsObjCmd(
    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 strings. */
{
    char buf[TCL_INTEGER_SPACE];
    int val;
    (void)dummy;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (strcmp(Tcl_GetString(objv[1]), "cyvscroll") == 0) {
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
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







-
-
-

-


















-
+







    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);
	    longLongInt, (unsigned long long)longLongInt);
    Tcl_AppendResult(interp, buffer, NULL);
    return TCL_OK;
}

#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
/*
 *----------------------------------------------------------------------
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
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







-
+

-
+








-
-







 *		CustomOptionFree	Free storage for internal rep of option.
 *
 *----------------------------------------------------------------------
 */

static int
CustomOptionSet(
    ClientData dummy,
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    Tk_Window tkwin,
    TCL_UNUSED(Tk_Window),
    Tcl_Obj **value,
    char *recordPtr,
    TkSizeT internalOffset,
    char *saveInternalPtr,
    int flags)
{
    int objEmpty;
    char *newStr, *string, *internalPtr;
    (void)dummy;
    (void)tkwin;

    objEmpty = 0;

    if (internalOffset != TCL_INDEX_NONE) {
	internalPtr = recordPtr + internalOffset;
    } else {
	internalPtr = NULL;
2104
2105
2106
2107
2108
2109
2110
2111
2112


2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2092
2093
2094
2095
2096
2097
2098


2099
2100
2101
2102
2103



2104
2105
2106
2107
2108
2109
2110







-
-
+
+



-
-
-







    }

    return TCL_OK;
}

static Tcl_Obj *
CustomOptionGet(
    ClientData dummy,
    Tk_Window tkwin,
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    char *recordPtr,
    TkSizeT internalOffset)
{
    (void)dummy;
    (void)tkwin;

    return (Tcl_NewStringObj(*(char **)(recordPtr + internalOffset), -1));
}

static void
CustomOptionRestore(
    ClientData dummy,
    Tk_Window tkwin,

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 © 1992-1994 The Regents of the University of California.
 * Copyright © 1994-1996 Sun Microsystems, Inc.
 * Copyright © 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"
294
295
296
297
298
299
300
301

302
303
304

305
306
307
308
309
310
311
294
295
296
297
298
299
300

301
302
303

304
305
306
307
308
309
310
311







-
+


-
+







				 * 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 startOffset1;		/* Index in first line to start at. */
    TkSizeT startOffset;		/* Index in first line to start at. */
    int stopLine;		/* Last line to examine, or -1 when we search
				 * all available text. */
    TkSizeT stopOffset1;		/* Index to stop at, provided stopLine is not
    TkSizeT stopOffset;		/* Index to stop at, provided stopLine is not
				 * -1. */
    int numLines;		/* Total lines which are available. */
    int backwards;		/* Searching forwards or backwards. */
    Tcl_Obj *varPtr;		/* If non-NULL, store length(s) of match(es)
				 * in this variable. */
    Tcl_Obj *countPtr;		/* Keeps track of currently found lengths. */
    Tcl_Obj *resPtr;		/* Keeps track of currently found locations */
666
667
668
669
670
671
672
673

674
675
676
677
678
679
680
666
667
668
669
670
671
672

673
674
675
676
677
678
679
680







-
+







	return TCL_ERROR;
    }
    if (ConfigureText(interp, textPtr, objc-2, objv+2) != TCL_OK) {
	Tk_DestroyWindow(textPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, TkNewWindowObj(textPtr->tkwin));
    Tcl_SetObjResult(interp, Tk_NewWindowObj(textPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * TextWidgetObjCmd --
697
698
699
700
701
702
703
704

705
706
707
708
709
710
711
697
698
699
700
701
702
703

704
705
706
707
708
709
710
711







-
+







    ClientData clientData,	/* Information about text widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkText *textPtr = (TkText *)clientData;
    int result = TCL_OK;
    int index;
    int idx;

    static const char *const optionStrings[] = {
	"bbox", "cget", "compare", "configure", "count", "debug", "delete",
	"dlineinfo", "dump", "edit", "get", "image", "index", "insert",
	"mark", "peer", "pendingsync", "replace", "scan", "search",
	"see", "sync", "tag", "window", "xview", "yview", NULL
    };
720
721
722
723
724
725
726
727

728
729
730
731
732

733
734
735
736
737
738
739
720
721
722
723
724
725
726

727
728
729
730
731

732
733
734
735
736
737
738
739







-
+




-
+








    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) {
	    sizeof(char *), "option", 0, &idx) != TCL_OK) {
	return TCL_ERROR;
    }
    textPtr->refCount++;

    switch ((enum options) index) {
    switch ((enum options) idx) {
    case TEXT_BBOX: {
	int x, y, width, height;
	const TkTextIndex *indexPtr;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    result = TCL_ERROR;
861
862
863
864
865
866
867
868

869
870
871
872
873
874
875
861
862
863
864
865
866
867

868
869
870
871
872
873
874
875







-
+







	    result = TCL_ERROR;
	    goto done;
	}

	for (i = 2; i < objc-2; i++) {
	    int value;
	    TkSizeT length;
	    const char *option = TkGetStringFromObj(objv[i], &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)) {
1047
1048
1049
1050
1051
1052
1053
1054

1055
1056
1057
1058
1059
1060
1061
1047
1048
1049
1050
1051
1052
1053

1054
1055
1056
1057
1058
1059
1060
1061







-
+







	} 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:
1157
1158
1159
1160
1161
1162
1163
1164

1165
1166
1167
1168
1169
1170
1171
1157
1158
1159
1160
1161
1162
1163

1164
1165
1166
1167
1168
1169
1170
1171







-
+







		memset(useIdx, 0, objc);

		/*
		 * Do a decreasing order sort so that we delete the end ranges
		 * first to maintain index consistency.
		 */

		qsort(indices, objc / 2,
		qsort(indices, (size_t) objc / 2,
			2 * sizeof(TkTextIndex), TextIndexSortProc);
		lastStart = NULL;

		/*
		 * Second pass will handle bogus ranges (end < start) and
		 * overlapping ranges.
		 */
1271
1272
1273
1274
1275
1276
1277
1278

1279
1280
1281
1282
1283

1284
1285
1286
1287
1288
1289
1290
1271
1272
1273
1274
1275
1276
1277

1278
1279
1280
1281
1282

1283
1284
1285
1286
1287
1288
1289
1290







-
+




-
+







	/*
	 * 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
1749
1750
1751
1752
1753
1754
1755

1756
1757
1758
1759
1760
1761
1762
1763







-
+







	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}
	peersObj = Tcl_NewObj();
	while (tPtr != NULL) {
	    if (tPtr != textPtr) {
		Tcl_ListObjAppendElement(NULL, peersObj,
			TkNewWindowObj(tPtr->tkwin));
			Tk_NewWindowObj(tPtr->tkwin));
	    }
	    tPtr = tPtr->next;
	}
	Tcl_SetObjResult(interp, peersObj);
    }
    }

2632
2633
2634
2635
2636
2637
2638
2639

2640
2641
2642
2643
2644
2645
2646
2632
2633
2634
2635
2636
2637
2638

2639
2640
2641
2642
2643
2644
2645
2646







-
+







{
    int lineIndex;
    TkSizeT 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
3169
3170
3171
3172
3173
3174
3175
3176

3177
3178
3179
3180
3181
3182
3183
3169
3170
3171
3172
3173
3174
3175

3176
3177
3178
3179
3180
3181
3182
3183







-
+







     * deleted but tags might be removed.
     */

    line1 = TkBTreeLinesTo(textPtr, index1.linePtr);
    line2 = TkBTreeLinesTo(textPtr, index2.linePtr);
    if (line2 == TkBTreeNumLines(sharedTextPtr->tree, textPtr)) {
	TkTextTag **arrayPtr;
	int arraySize, i;
	int arraySize;
	TkTextIndex oldIndex2;

	oldIndex2 = index2;
	TkTextIndexBackChars(NULL, &oldIndex2, 1, &index2, COUNT_INDICES);
	line2--;
	if ((index1.byteIndex == 0) && (line1 != 0)) {
	    TkTextIndexBackChars(NULL, &index1, 1, &index1, COUNT_INDICES);
3553
3554
3555
3556
3557
3558
3559
3560

3561
3562
3563
3564
3565
3566
3567
3553
3554
3555
3556
3557
3558
3559

3560
3561
3562
3563
3564
3565
3566
3567







-
+








void
TkTextLostSelection(
    ClientData clientData)	/* Information about text widget. */
{
    TkText *textPtr = (TkText *)clientData;

    if (TkpAlwaysShowSelection(textPtr->tkwin)) {
    if (Tk_AlwaysShowSelection(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
3611
3612
3613
3614
3615
3616
3617

3618
3619
3620
3621
3622
3623
3624
3625







-
+







    TkText *textPtr)
{
    /*
     * Send an event that the selection changed. This is equivalent to:
     *     event generate $textWidget <<Selection>>
     */

    TkSendVirtualEvent(textPtr->tkwin, "Selection", NULL);
    Tk_SendVirtualEvent(textPtr->tkwin, "Selection", NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * TextBlinkProc --
 *
4284
4285
4286
4287
4288
4289
4290
4291

4292
4293
4294
4295
4296
4297
4298
4284
4285
4286
4287
4288
4289
4290

4291
4292
4293
4294
4295
4296
4297
4298







-
+







	/*
	 * 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->stopOffset1 + 1)) {
		(matchOffset + 1 >= searchSpecPtr->stopOffset + 1)) {
	    return 0;
	}
    }

    /*
     * Calculate the character count, which may need augmenting if there are
     * embedded windows or elidden text.
4309
4310
4311
4312
4313
4314
4315
4316

4317
4318
4319
4320
4321
4322
4323
4309
4310
4311
4312
4313
4314
4315

4316
4317
4318
4319
4320
4321
4322
4323







-
+







    /*
     * If we're using strict limits checking, ensure that the match with its
     * full length fits inside the given range.
     */

    if (searchSpecPtr->strictLimits && lineNum == searchSpecPtr->stopLine) {
	if (searchSpecPtr->backwards ^
		((matchOffset + numChars + 1) > searchSpecPtr->stopOffset1 + 1)) {
		((matchOffset + numChars + 1) > searchSpecPtr->stopOffset + 1)) {
	    return 0;
	}
    }

    /*
     * The index information returned by the regular expression parser only
     * considers textual information: it doesn't account for embedded windows,
4535
4536
4537
4538
4539
4540
4541
4542
4543


4544
4545
4546
4547
4548
4549
4550
4535
4536
4537
4538
4539
4540
4541


4542
4543
4544
4545
4546
4547
4548
4549
4550







-
-
+
+







	}
    }

    /*
     * Parse the elements of the list one at a time to fill in the array.
     */

    tabArrayPtr = (TkTextTabArray *)ckalloc(sizeof(TkTextTabArray)
	    + (count - 1) * sizeof(TkTextTab));
    tabArrayPtr = (TkTextTabArray *)ckalloc(offsetof(TkTextTabArray, tabs)
	    + count * sizeof(TkTextTab));
    tabArrayPtr->numTabs = 0;
    prevStop = 0.0;
    lastStop = 0.0;
    for (i = 0, tabPtr = &tabArrayPtr->tabs[0]; i < objc; i++, tabPtr++) {
	int index;

	/*
4755
4756
4757
4758
4759
4760
4761
4762

4763
4764
4765
4766
4767
4768
4769
4755
4756
4757
4758
4759
4760
4761

4762
4763
4764
4765
4766
4767
4768
4769







-
+







    } else {
	TkSizeT 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;
    }
5056
5057
5058
5059
5060
5061
5062
5063

5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5056
5057
5058
5059
5060
5061
5062

5063
5064
5065
5066

5067
5068
5069
5070
5071
5072
5073







-
+



-







DumpSegment(
    TkText *textPtr,
    Tcl_Interp *interp,
    const char *key,		/* Segment type key. */
    const char *value,		/* Segment value. */
    Tcl_Obj *command,		/* Script callback. */
    const TkTextIndex *index,	/* index with line/byte position info. */
    int what)			/* Look for TK_DUMP_INDEX bit. */
    TCL_UNUSED(int))		/* Look for TK_DUMP_INDEX bit. */
{
    char buffer[TK_POS_CHARS];
    Tcl_Obj *values[3], *tuple;
    (void)what;

    TkTextPrintIndex(textPtr, index, buffer);
    values[0] = Tcl_NewStringObj(key, -1);
    values[1] = Tcl_NewStringObj(value, -1);
    values[2] = Tcl_NewStringObj(buffer, -1);
    tuple = Tcl_NewListObj(3, values);
    if (command == NULL) {
5486
5487
5488
5489
5490
5491
5492
5493

5494
5495
5496
5497
5498
5499
5500
5485
5486
5487
5488
5489
5490
5491

5492
5493
5494
5495
5496
5497
5498
5499







-
+







static void
GenerateModifiedEvent(
    TkText *textPtr)	/* Information about text widget. */
{
    for (textPtr = textPtr->sharedTextPtr->peers; textPtr != NULL;
	    textPtr = textPtr->next) {
	Tk_MakeWindowExist(textPtr->tkwin);
	TkSendVirtualEvent(textPtr->tkwin, "Modified", NULL);
	Tk_SendVirtualEvent(textPtr->tkwin, "Modified", NULL);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * GenerateUndoStackEvent --
5516
5517
5518
5519
5520
5521
5522
5523

5524
5525
5526
5527
5528
5529
5530
5515
5516
5517
5518
5519
5520
5521

5522
5523
5524
5525
5526
5527
5528
5529







-
+







static void
GenerateUndoStackEvent(
    TkText *textPtr)	/* Information about text widget. */
{
    for (textPtr = textPtr->sharedTextPtr->peers; textPtr != NULL;
	    textPtr = textPtr->next) {
	Tk_MakeWindowExist(textPtr->tkwin);
	TkSendVirtualEvent(textPtr->tkwin, "UndoStack", NULL);
	Tk_SendVirtualEvent(textPtr->tkwin, "UndoStack", NULL);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateDirtyFlag --
5660
5661
5662
5663
5664
5665
5666
5667

5668
5669
5670
5671
5672
5673
5674
5659
5660
5661
5662
5663
5664
5665

5666
5667
5668
5669
5670
5671
5672
5673







-
+







    /*
     * Find the starting line and starting offset (measured in Unicode chars
     * for regexp search, utf-8 bytes for exact search).
     */

    if (searchSpecPtr->lineIndexProc(interp, fromPtr, searchSpecPtr,
	    &searchSpecPtr->startLine,
	    &searchSpecPtr->startOffset1) != TCL_OK) {
	    &searchSpecPtr->startOffset) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Find the optional end location, similarly.
     */

5691
5692
5693
5694
5695
5696
5697
5698

5699
5700
5701
5702
5703
5704
5705
5690
5691
5692
5693
5694
5695
5696

5697
5698
5699
5700
5701
5702
5703
5704







-
+







	if (TkTextIndexCmp(indexFromPtr, indexToPtr) ==
		(searchSpecPtr->backwards ? -1 : 1)) {
	    return TCL_OK;
	}

	if (searchSpecPtr->lineIndexProc(interp, toPtr, searchSpecPtr,
		&searchSpecPtr->stopLine,
		&searchSpecPtr->stopOffset1) != TCL_OK) {
		&searchSpecPtr->stopOffset) != TCL_OK) {
	    return TCL_ERROR;
	}
    } else {
	searchSpecPtr->stopLine = -1;
    }

    /*
5825
5826
5827
5828
5829
5830
5831
5832

5833
5834
5835
5836
5837
5838
5839
5824
5825
5826
5827
5828
5829
5830

5831
5832
5833
5834
5835
5836
5837
5838







-
+








	/*
	 * We only need to set the matchLength once for exact searches, and we
	 * do it here. It is also used below as the actual pattern length, so
	 * it has dual purpose.
	 */

	pattern = TkGetStringFromObj(patObj, &matchLength);
	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.
	 */
5890
5891
5892
5893
5894
5895
5896
5897

5898
5899
5900
5901
5902
5903
5904
5889
5890
5891
5892
5893
5894
5895

5896
5897
5898
5899
5900
5901
5902
5903







-
+







	     * crash below.
	     */

	    goto nextLine;
	}

	if (lineNum == searchSpecPtr->stopLine && searchSpecPtr->backwards) {
	    firstOffset = searchSpecPtr->stopOffset1;
	    firstOffset = searchSpecPtr->stopOffset;
	} else {
	    firstOffset = 0;
	}

	if (alreadySearchOffset >= 0) {
	    if (searchSpecPtr->backwards) {
		if (alreadySearchOffset < lastOffset) {
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
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







-
-
+
+










-
-
+
+







		/*
		 * Forward search and first pass, or backward search and
		 * second pass.
		 *
		 * Only use the last part of the line.
		 */

		if (searchSpecPtr->startOffset1 + 1 > (TkSizeT)firstOffset + 1) {
		    firstOffset = searchSpecPtr->startOffset1;
		if (searchSpecPtr->startOffset + 1 > (TkSizeT)firstOffset + 1) {
		    firstOffset = searchSpecPtr->startOffset;
		}
		if ((firstOffset >= lastOffset)
		    && ((lastOffset != 0) || searchSpecPtr->exact)) {
		    goto nextLine;
		}
	    } else {
		/*
		 * Use only the first part of the line.
		 */

		if (searchSpecPtr->startOffset1 + 1 < (TkSizeT)lastOffset + 1) {
		    lastOffset = searchSpecPtr->startOffset1;
		if (searchSpecPtr->startOffset + 1 < (TkSizeT)lastOffset + 1) {
		    lastOffset = searchSpecPtr->startOffset;
		}
	    }
	}

	/*
	 * Check for matches within the current line 'lineNum'. If so, and if
	 * we're searching backwards or for all matches, repeat the search
6773
6774
6775
6776
6777
6778
6779
6780
6781


6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6772
6773
6774
6775
6776
6777
6778


6779
6780
6781
6782
6783
6784
6785


6786
6787
6788
6789
6790
6791
6792







-
-
+
+





-
-







 *	Creates a new Tcl_Obj.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
GetLineStartEnd(
    ClientData dummy,
    Tk_Window tkwin,
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    char *recordPtr,		/* Pointer to widget record. */
    TkSizeT internalOffset)		/* Offset within *recordPtr containing the
				 * line value. */
{
    TkTextLine *linePtr = *(TkTextLine **)(recordPtr + internalOffset);
    (void)dummy;
    (void)tkwin;

    if (linePtr == NULL) {
	return Tcl_NewObj();
    }
    return Tcl_NewWideIntObj(1 + TkBTreeLinesTo(NULL, linePtr));
}

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
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







-
+

-
+












-
-







 *	that the specified string was empty and that is acceptable.
 *
 *----------------------------------------------------------------------
 */

static int
SetLineStartEnd(
    ClientData dummy,
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interp; may be used for errors. */
    Tk_Window tkwin,		/* Window for which option is being set. */
    TCL_UNUSED(Tk_Window),	/* Window for which option is being set. */
    Tcl_Obj **value,		/* Pointer to the pointer to the value object.
				 * We use a pointer to the pointer because we
				 * may need to return a value (NULL). */
    char *recordPtr,		/* Pointer to storage for the widget record. */
    TkSizeT internalOffset,		/* Offset within *recordPtr at which the
				 * internal value is to be stored. */
    char *oldInternalPtr,	/* Pointer to storage for the old value. */
    int flags)			/* Flags for the option, set Tk_SetOptions. */
{
    TkTextLine *linePtr = NULL;
    char *internalPtr;
    TkText *textPtr = (TkText *) recordPtr;
    (void)dummy;
    (void)tkwin;

    if (internalOffset != TCL_INDEX_NONE) {
	internalPtr = (char *)recordPtr + internalOffset;
    } else {
	internalPtr = NULL;
    }

6871
6872
6873
6874
6875
6876
6877
6878
6879


6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6866
6867
6868
6869
6870
6871
6872


6873
6874
6875
6876
6877



6878
6879
6880
6881
6882
6883
6884







-
-
+
+



-
-
-







 *	Restores the old value.
 *
 *----------------------------------------------------------------------
 */

static void
RestoreLineStartEnd(
    ClientData dummy,
    Tk_Window tkwin,
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    char *internalPtr,		/* Pointer to storage for value. */
    char *oldInternalPtr)	/* Pointer to old value. */
{
    (void)dummy;
    (void)tkwin;

    *(TkTextLine **)internalPtr = *(TkTextLine **)oldInternalPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * ObjectIsEmpty --
6933
6934
6935
6936
6937
6938
6939
6940

6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6925
6926
6927
6928
6929
6930
6931

6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942

6943
6944
6945
6946
6947
6948
6949







-
+










-







 *	Depends on option; see below.
 *
 *----------------------------------------------------------------------
 */

int
TkpTesttextCmd(
    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 strings. */
{
    TkText *textPtr;
    size_t len;
    int lineIndex, byteIndex, byteOffset;
    TkTextIndex index;
    char buf[64];
    Tcl_CmdInfo info;
    (void)dummy;

    if (objc < 3) {
	return TCL_ERROR;
    }

    if (Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &info) == 0) {
	return TCL_ERROR;

Changes to generic/tkText.h.

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







-
+







				 * type. */
    struct TkTextSegment *nextPtr;
				/* Next in list of segments for this line, or
				 * NULL for end of list. */
    TkSizeT size;			/* Size of this segment (# of bytes of index
				 * space it occupies). */
    union {
	char chars[2];		/* Characters that make up character info.
	char chars[TKFLEXARRAY];		/* Characters that make up character info.
				 * Actual length varies to hold as many
				 * characters as needed.*/
	TkTextToggle toggle;	/* Information about tag toggle. */
	TkTextMark mark;	/* Information about mark. */
	TkTextEmbWindow ew;	/* Information about embedded window. */
	TkTextEmbImage ei;	/* Information about embedded image. */
    } body;
485
486
487
488
489
490
491
492

493
494
495
496
497
498
499
485
486
487
488
489
490
491

492
493
494
495
496
497
498
499







-
+







typedef struct TkTextTabArray {
    int numTabs;		/* Number of tab stops. */
    double lastTab;		/* The accurate fractional pixel position of
				 * the last tab. */
    double tabIncrement;	/* The accurate fractional pixel increment
				 * between interpolated tabs we have to create
				 * when we exceed numTabs. */
    TkTextTab tabs[1];		/* Array of tabs. The actual size will be
    TkTextTab tabs[TKFLEXARRAY];/* Array of tabs. The actual size will be
				 * numTabs. THIS FIELD MUST BE THE LAST IN THE
				 * STRUCTURE. */
} TkTextTabArray;

/*
 * Enumeration defining the edit modes of the widget.
 */

Changes to generic/tkTextBTree.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







-
-
+
+







/*
 * tkTextBTree.c --
 *
 *	This file contains code that manages the B-tree representation of text
 *	for Tk's text widget and implements character and toggle segment
 *	types.
 *
 * Copyright (c) 1992-1994 The Regents of the University of California.
 * Copyright (c) 1994-1995 Sun Microsystems, Inc.
 * Copyright © 1992-1994 The Regents of the University of California.
 * Copyright © 1994-1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkText.h"
4165
4166
4167
4168
4169
4170
4171
4172

4173
4174
4175
4176
4177
4178
4179
4165
4166
4167
4168
4169
4170
4171

4172
4173
4174
4175
4176
4177
4178
4179







-
+







	    }
	}

	while (nodePtr->numChildren < MIN_CHILDREN) {
	    Node *otherPtr;
	    Node *halfwayNodePtr = NULL;       /* Initialization needed only */
	    TkTextLine *halfwayLinePtr = NULL; /* to prevent cc warnings. */
	    int totalChildren, firstChildren, i;
	    int totalChildren, firstChildren;

	    /*
	     * Too few children for this node. If this is the root then, it's
	     * OK for it to have less than MIN_CHILDREN children as long as
	     * it's got at least two. If it has only one (and isn't at level
	     * 0), then chop the root node out of the tree and use its child
	     * as the new root.
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
4226
4227
4228
4229
4230
4231
4232


4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246


4247
4248
4249
4250
4251
4252
4253







-
-














-
-







	    firstChildren = totalChildren/2;
	    if (nodePtr->children.nodePtr == NULL) {
		nodePtr->children = otherPtr->children;
		otherPtr->children.nodePtr = NULL;
		otherPtr->children.linePtr = NULL;
	    }
	    if (nodePtr->level == 0) {
		TkTextLine *linePtr;

		for (linePtr = nodePtr->children.linePtr, i = 1;
			linePtr->nextPtr != NULL;
			linePtr = linePtr->nextPtr, i++) {
		    if (i == firstChildren) {
			halfwayLinePtr = linePtr;
		    }
		}
		linePtr->nextPtr = otherPtr->children.linePtr;
		while (i <= firstChildren) {
		    halfwayLinePtr = linePtr;
		    linePtr = linePtr->nextPtr;
		    i++;
		}
	    } else {
		Node *childPtr;

		for (childPtr = nodePtr->children.nodePtr, i = 1;
			childPtr->nextPtr != NULL;
			childPtr = childPtr->nextPtr, i++) {
		    if (i <= firstChildren) {
			if (i == firstChildren) {
			    halfwayNodePtr = childPtr;
			}
4588
4589
4590
4591
4592
4593
4594
4595

4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4584
4585
4586
4587
4588
4589
4590

4591
4592
4593

4594
4595
4596
4597
4598
4599
4600







-
+


-







 *--------------------------------------------------------------
 */

static TkTextSegment *
CharCleanupProc(
    TkTextSegment *segPtr,	/* Pointer to first of two adjacent segments
				 * to join. */
    TkTextLine *linePtr)	/* Line containing segments (not used). */
    TCL_UNUSED(TkTextLine *))	/* Line containing segments (not used). */
{
    TkTextSegment *segPtr2, *newPtr;
    (void)linePtr;

    segPtr2 = segPtr->nextPtr;
    if ((segPtr2 == NULL) || (segPtr2->typePtr != &tkTextCharType)) {
	return segPtr;
    }
    newPtr = (TkTextSegment *)ckalloc(CSEG_SIZE(segPtr->size + segPtr2->size));
    newPtr->typePtr = &tkTextCharType;
4628
4629
4630
4631
4632
4633
4634
4635
4636


4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4623
4624
4625
4626
4627
4628
4629


4630
4631
4632
4633
4634



4635
4636
4637
4638
4639
4640
4641







-
-
+
+



-
-
-







 *
 *--------------------------------------------------------------
 */

static int
CharDeleteProc(
    TkTextSegment *segPtr,	/* Segment to delete. */
    TkTextLine *linePtr,	/* Line containing segment. */
    int treeGone)		/* Non-zero means the entire tree is being
    TCL_UNUSED(TkTextLine *),	/* Line containing segment. */
    TCL_UNUSED(int))		/* Non-zero means the entire tree is being
				 * deleted, so everything must get cleaned
				 * up. */
{
    (void)linePtr;
    (void)treeGone;

    ckfree(segPtr);
    return 0;
}

/*
 *--------------------------------------------------------------
 *
4660
4661
4662
4663
4664
4665
4666
4667

4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4652
4653
4654
4655
4656
4657
4658

4659
4660


4661
4662
4663
4664
4665
4666
4667







-
+

-
-







 *
 *--------------------------------------------------------------
 */

static void
CharCheckProc(
    TkTextSegment *segPtr,	/* Segment to check. */
    TkTextLine *linePtr)	/* Line containing segment. */
    TCL_UNUSED(TkTextLine *))	/* Line containing segment. */
{
    (void)linePtr;

    /*
     * 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.
     */

Changes to generic/tkTextDisp.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








-
-
+
+







/*
 * tkTextDisp.c --
 *
 *	This module provides facilities to display text widgets. It is the
 *	only place where information is kept about the screen layout of text
 *	widgets. (Well, strictly, each TkTextLine and B-tree node caches its
 *	last observed pixel height, but that information originates here).
 *
 * Copyright (c) 1992-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright  © 1992-1994 The Regents of the University of California.
 * Copyright  © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkText.h"
436
437
438
439
440
441
442
443

444
445
446
447
448


449
450
451
452
453
454
455
436
437
438
439
440
441
442

443
444
445
446


447
448
449
450
451
452
453
454
455







-
+



-
-
+
+







} TextDInfo;

/*
 * In TkTextDispChunk structures for character segments, the clientData field
 * points to one of the following structures:
 */

#if !TK_LAYOUT_WITH_BASE_CHUNKS
#if !defined(TK_LAYOUT_WITH_BASE_CHUNKS)

typedef struct CharInfo {
    int numBytes;		/* Number of bytes to display. */
    char chars[1];		/* UTF characters to display. Actual size will
				 * be numBytes, not 1. THIS MUST BE THE LAST
    char chars[TKFLEXARRAY];		/* UTF characters to display.
				 * Allocated as large as necessary. THIS MUST BE THE LAST
				 * FIELD IN THE STRUCTURE. */
} CharInfo;

#else /* TK_LAYOUT_WITH_BASE_CHUNKS */

typedef struct CharInfo {
    TkTextDispChunk *baseChunkPtr;
548
549
550
551
552
553
554
555

556
557
558
559
560
561
562
548
549
550
551
552
553
554

555
556
557
558
559
560
561
562







-
+







static void		CharDisplayProc(TkText *textPtr,
			    TkTextDispChunk *chunkPtr, int x, int y,
			    int height, int baseline, Display *display,
			    Drawable dst, int screenY);
static int		CharMeasureProc(TkTextDispChunk *chunkPtr, int x);
static void		CharUndisplayProc(TkText *textPtr,
			    TkTextDispChunk *chunkPtr);
#if TK_LAYOUT_WITH_BASE_CHUNKS
#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
static void		FinalizeBaseChunk(TkTextDispChunk *additionalChunkPtr);
static void		FreeBaseChunk(TkTextDispChunk *baseChunkPtr);
static int		IsSameFGStyle(TextStyle *style1, TextStyle *style2);
static void		RemoveFromBaseChunk(TkTextDispChunk *chunkPtr);
#endif
/*
 * Definitions of elided procs. Compiler can't inline these since we use
1363
1364
1365
1366
1367
1368
1369
1370

1371
1372
1373
1374
1375
1376
1377
1363
1364
1365
1366
1367
1368
1369

1370
1371
1372
1373
1374
1375
1376
1377







-
+








    while (segPtr != NULL) {
	/*
	 * Every logical line still gets at least one chunk due to
	 * expectations in the rest of the code, but we are able to skip
	 * elided portions of the line quickly.
	 *
	 * If current chunk is elided and last chunk was too, coalese.
	 * If current chunk is elided and last chunk was too, coalesce.
	 *
	 * This also means that each logical line which is entirely elided
	 * still gets laid out into a DLine, but with zero height. This isn't
	 * particularly a problem, but it does seem somewhat unnecessary. We
	 * may wish to redesign the code to remove these zero height DLines in
	 * the future.
	 */
1504
1505
1506
1507
1508
1509
1510
1511

1512
1513
1514
1515
1516
1517
1518
1504
1505
1506
1507
1508
1509
1510

1511
1512
1513
1514
1515
1516
1517
1518







-
+







			maxBytes = (p + 1 - segPtr->body.chars) - byteOffset;
			gotTab = 1;
			break;
		    }
		}
	    }

#if TK_LAYOUT_WITH_BASE_CHUNKS
#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
	    if (baseCharChunkPtr != NULL) {
		int expectedX =
			((BaseCharInfo *) baseCharChunkPtr->clientData)->width
			+ baseCharChunkPtr->x;

		if ((expectedX != x) || !IsSameFGStyle(
			baseCharChunkPtr->stylePtr, chunkPtr->stylePtr)) {
1646
1647
1648
1649
1650
1651
1652
1653

1654
1655
1656
1657
1658
1659
1660
1646
1647
1648
1649
1650
1651
1652

1653
1654
1655
1656
1657
1658
1659
1660







-
+







		    goto connectNextLogicalLine;
		}
	    }
	}

	chunkPtr = NULL;
    }
#if TK_LAYOUT_WITH_BASE_CHUNKS
#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
    FinalizeBaseChunk(NULL);
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
    if (noCharsYet) {
	dlPtr->spaceAbove = 0;
	dlPtr->spaceBelow = 0;
	dlPtr->length = 0;

1705
1706
1707
1708
1709
1710
1711
1712

1713
1714
1715
1716
1717
1718
1719
1705
1706
1707
1708
1709
1710
1711

1712
1713
1714
1715
1716
1717
1718
1719







-
+







	    if (breakChunkPtr->undisplayProc != NULL) {
		breakChunkPtr->undisplayProc(textPtr, breakChunkPtr);
	    }
	    segPtr = TkTextIndexToSeg(&breakIndex, &byteOffset);
	    segPtr->typePtr->layoutProc(textPtr, &breakIndex, segPtr,
		    byteOffset, maxX, breakByteOffset, 0, wrapMode,
		    breakChunkPtr);
#if TK_LAYOUT_WITH_BASE_CHUNKS
#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
	    FinalizeBaseChunk(NULL);
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
	}
	lastChunkPtr = breakChunkPtr;
	wholeLine = 0;
    }

3160
3161
3162
3163
3164
3165
3166
3167
3168


3169
3170
3171
3172
3173
3174
3175
3160
3161
3162
3163
3164
3165
3166


3167
3168
3169
3170
3171
3172
3173
3174
3175







-
-
+
+








    if (NewSyncState != OldSyncState) {
	if (NewSyncState) {
	    textPtr->dInfoPtr->flags &= ~OUT_OF_SYNC;
	} else {
	    textPtr->dInfoPtr->flags |= OUT_OF_SYNC;
	}
        TkSendVirtualEvent(textPtr->tkwin, "WidgetViewSync",
                           Tcl_NewBooleanObj(NewSyncState));
	Tk_SendVirtualEvent(textPtr->tkwin, "WidgetViewSync",
		Tcl_NewBooleanObj(NewSyncState));
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextUpdateLineMetrics --
5272
5273
5274
5275
5276
5277
5278
5279

5280
5281
5282
5283
5284
5285
5286
5272
5273
5274
5275
5276
5277
5278

5279
5280
5281
5282
5283
5284
5285
5286







-
+








    if (!IsStartOfNotMergedLine(textPtr, &textPtr->topIndex)) {
	TkTextFindDisplayLineEnd(textPtr, &textPtr->topIndex, 0, NULL);
    }

    /*
     * Invalidate cached scrollbar positions, so that scrollbars sliders will
     * be udpated.
     * be updated.
     */

    dInfoPtr->xScrollFirst = dInfoPtr->xScrollLast = -1;
    dInfoPtr->yScrollFirst = dInfoPtr->yScrollLast = -1;

    if (mask & TK_TEXT_LINE_GEOMETRY) {

6178
6179
6180
6181
6182
6183
6184
6185

6186
6187
6188
6189
6190
6191
6192
6178
6179
6180
6181
6182
6183
6184

6185
6186
6187
6188
6189
6190
6191
6192







-
+







    /*
     * 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;
7538
7539
7540
7541
7542
7543
7544
7545

7546
7547

7548
7549
7550
7551
7552


7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579


7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7538
7539
7540
7541
7542
7543
7544

7545
7546

7547
7548
7549
7550


7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561




7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573


7574
7575
7576
7577



7578
7579
7580
7581
7582
7583
7584







-
+

-
+



-
-
+
+









-
-
-
-












-
-
+
+


-
-
-








/*
 * Get bounding-box information about an elided chunk.
 */

static void
ElideBboxProc(
    TkText *textPtr,
    TCL_UNUSED(TkText *),
    TkTextDispChunk *chunkPtr,	/* Chunk containing desired char. */
    int index,			/* Index of desired character within the
    TCL_UNUSED(int),		/* Index of desired character within the
				 * chunk. */
    int y,			/* Topmost pixel in area allocated for this
				 * line. */
    int lineHeight,		/* Height of line, in pixels. */
    int baseline,		/* Location of line's baseline, in pixels
    TCL_UNUSED(int),	/* Height of line, in pixels. */
    TCL_UNUSED(int),	/* Location of line's baseline, in pixels
				 * measured down from y. */
    int *xPtr, int *yPtr,	/* Gets filled in with coords of character's
				 * upper-left pixel. X-coord is in same
				 * coordinate system as chunkPtr->x. */
    int *widthPtr,		/* Gets filled in with width of character, in
				 * pixels. */
    int *heightPtr)		/* Gets filled in with height of character, in
				 * pixels. */
{
    (void)textPtr;
    (void)index;
    (void)lineHeight;
    (void)baseline;

    *xPtr = chunkPtr->x;
    *yPtr = y;
    *widthPtr = *heightPtr = 0;
}

/*
 * Measure an elided chunk.
 */

static int
ElideMeasureProc(
    TkTextDispChunk *chunkPtr,	/* Chunk containing desired coord. */
    int x)			/* X-coordinate, in same coordinate system as
    TCL_UNUSED(TkTextDispChunk *),	/* Chunk containing desired coord. */
    TCL_UNUSED(int))		/* X-coordinate, in same coordinate system as
				 * chunkPtr->x. */
{
    (void)chunkPtr;
    (void)x;

    return 0 /*chunkPtr->numBytes - 1*/;
}

/*
 *--------------------------------------------------------------
 *
 * TkTextCharLayoutProc --
7604
7605
7606
7607
7608
7609
7610
7611
7612


7613
7614
7615
7616
7617
7618
7619
7597
7598
7599
7600
7601
7602
7603


7604
7605
7606
7607
7608
7609
7610
7611
7612







-
-
+
+







 *	Memory is allocated to hold additional information about the chunk.
 *
 *--------------------------------------------------------------
 */

int
TkTextCharLayoutProc(
    TkText *textPtr,		/* Text widget being layed out. */
    TkTextIndex *indexPtr,	/* Index of first character to lay out
    TCL_UNUSED(TkText *),	/* Text widget being layed out. */
    TCL_UNUSED(TkTextIndex *),	/* Index of first character to lay out
				 * (corresponds to segPtr and offset). */
    TkTextSegment *segPtr,	/* Segment being layed out. */
    TkSizeT byteOffset,		/* Byte offset within segment of first
				 * character to consider. */
    int maxX,			/* Chunk must not occupy pixels at this
				 * position or higher. */
    TkSizeT maxBytes,		/* Chunk must not include more than this many
7631
7632
7633
7634
7635
7636
7637
7638

7639
7640
7641
7642
7643
7644
7645
7646
7647
7648
7649
7650
7651
7652
7653
7654
7655
7656
7657
7658
7659
7660
7661
7662
7663
7664
7665

7666
7667
7668
7669
7670
7671
7672
7624
7625
7626
7627
7628
7629
7630

7631
7632
7633
7634
7635
7636


7637
7638
7639
7640
7641
7642
7643
7644
7645
7646
7647
7648
7649
7650
7651
7652
7653
7654
7655

7656
7657
7658
7659
7660
7661
7662
7663







-
+





-
-



















-
+







    Tk_Font tkfont;
    int nextX, count;
    TkSizeT bytesThatFit;
    CharInfo *ciPtr;
    char *p;
    TkTextSegment *nextPtr;
    Tk_FontMetrics fm;
#if TK_LAYOUT_WITH_BASE_CHUNKS
#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
    const char *line;
    int lineOffset;
    BaseCharInfo *bciPtr;
    Tcl_DString *baseString;
#endif
    (void)textPtr;
    (void)indexPtr;

    /*
     * Figure out how many characters will fit in the space we've got. Include
     * the next character, even though it won't fit completely, if any of the
     * following is true:
     *	 (a) the chunk contains no characters and the display line contains no
     *	     characters yet (i.e. the line isn't wide enough to hold even a
     *	     single character).
     *	 (b) at least one pixel of the character is visible, we have not
     *	     already exceeded the character limit, and the next character is a
     *	     white space character.
     * In the specific case of 'word' wrapping mode however, include all space
     * characters following the characters that fit in the space we've got,
     * even if no pixel of them is visible.
     */

    p = segPtr->body.chars + byteOffset;
    tkfont = chunkPtr->stylePtr->sValuePtr->tkfont;

#if TK_LAYOUT_WITH_BASE_CHUNKS
#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
    if (baseCharChunkPtr == NULL) {
	baseCharChunkPtr = chunkPtr;
	bciPtr = ckalloc(sizeof(BaseCharInfo));
	baseString = &bciPtr->baseChars;
	Tcl_DStringInit(baseString);
	bciPtr->width = 0;

7695
7696
7697
7698
7699
7700
7701
7702

7703
7704
7705
7706
7707
7708
7709
7686
7687
7688
7689
7690
7691
7692

7693
7694
7695
7696
7697
7698
7699
7700







-
+







#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */

    if (bytesThatFit + 1 <= maxBytes) {
	if ((bytesThatFit == 0) && noCharsYet) {
	    int ch;
	    int chLen = TkUtfToUniChar(p, &ch);

#if TK_LAYOUT_WITH_BASE_CHUNKS
#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
	    bytesThatFit = CharChunkMeasureChars(chunkPtr, line,
		    lineOffset+chLen, lineOffset, -1, chunkPtr->x, -1, 0,
		    &nextX);
#else /* !TK_LAYOUT_WITH_BASE_CHUNKS */
	    bytesThatFit = CharChunkMeasureChars(chunkPtr, p, chLen, 0, -1,
		    chunkPtr->x, -1, 0, &nextX);
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
7739
7740
7741
7742
7743
7744
7745
7746

7747
7748
7749
7750
7751
7752
7753
7730
7731
7732
7733
7734
7735
7736

7737
7738
7739
7740
7741
7742
7743
7744







-
+







	     * A newline character takes up no space, so if the previous
	     * character fits then so does the newline.
	     */

	    bytesThatFit++;
	}
	if (bytesThatFit == 0) {
#if TK_LAYOUT_WITH_BASE_CHUNKS
#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
	    chunkPtr->clientData = NULL;
	    if (chunkPtr == baseCharChunkPtr) {
		baseCharChunkPtr = NULL;
		Tcl_DStringFree(baseString);
	    } else {
		Tcl_DStringSetLength(baseString,lineOffset);
	    }
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
7763
7764
7765
7766
7767
7768
7769

7770
7771
7772
7773
7774
7775
7776
7777
7778
7779
7780

7781
7782
7783
7784
7785
7786
7787
7788







-
+










-
+







    chunkPtr->numBytes = bytesThatFit;
    chunkPtr->minAscent = fm.ascent + chunkPtr->stylePtr->sValuePtr->offset;
    chunkPtr->minDescent = fm.descent - chunkPtr->stylePtr->sValuePtr->offset;
    chunkPtr->minHeight = 0;
    chunkPtr->width = nextX - chunkPtr->x;
    chunkPtr->breakIndex = -1;

#if !TK_LAYOUT_WITH_BASE_CHUNKS
#if !defined(TK_LAYOUT_WITH_BASE_CHUNKS)
    ciPtr = (CharInfo *)ckalloc(offsetof(CharInfo, chars) + 1 + bytesThatFit);
    chunkPtr->clientData = ciPtr;
    memcpy(ciPtr->chars, p, bytesThatFit);
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */

    ciPtr->numBytes = bytesThatFit;
    if (p[bytesThatFit - 1] == '\n') {
	ciPtr->numBytes--;
    }

#if TK_LAYOUT_WITH_BASE_CHUNKS
#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
    /*
     * Final update for the current base chunk data.
     */

    Tcl_DStringSetLength(baseString,lineOffset+ciPtr->numBytes);
    bciPtr->width = nextX - baseCharChunkPtr->x;

7888
7889
7890
7891
7892
7893
7894
7895

7896
7897
7898
7899
7900
7901
7902
7879
7880
7881
7882
7883
7884
7885

7886
7887
7888
7889
7890
7891
7892
7893







-
+







    int *nextXPtr)		/* The function puts the newly calculated
				 * right border x-position of the span
				 * here. */
{
    Tk_Font tkfont = chunkPtr->stylePtr->sValuePtr->tkfont;
    CharInfo *ciPtr = (CharInfo *)chunkPtr->clientData;

#if !TK_LAYOUT_WITH_BASE_CHUNKS
#if !defined(TK_LAYOUT_WITH_BASE_CHUNKS)
    if (chars == NULL) {
	chars = ciPtr->chars;
	charsLen = ciPtr->numBytes;
    }
    if (end == -1) {
	end = charsLen;
    }
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
7952
7953
7954
7955
7956
7957
7958

7959
7960
7961
7962
7963
7964
7965

7966
7967
7968
7969

7970
7971
7972
7973
7974
7975
7976
7977

7978
7979
7980



7981
7982
7983
7984
7985
7986
7987
7988
7989

7990
7991
7992
7993
7994

7995
7996
7997
7998
7999
8000
8001
8002







-
+






-
+



-
+







-
+


-
-
-









-
+




-
+







 *	Graphics are drawn.
 *
 *--------------------------------------------------------------
 */

static void
CharDisplayProc(
    TkText *textPtr,
    TCL_UNUSED(TkText *),
    TkTextDispChunk *chunkPtr,	/* Chunk that is to be drawn. */
    int x,			/* X-position in dst at which to draw this
				 * chunk (may differ from the x-position in
				 * the chunk because of scrolling). */
    int y,			/* Y-position at which to draw this chunk in
				 * dst. */
    int height,			/* Total height of line. */
    TCL_UNUSED(int),		/* Total height of line. */
    int baseline,		/* Offset of baseline from y. */
    Display *display,		/* Display to use for drawing. */
    Drawable dst,		/* Pixmap or window in which to draw chunk. */
    int screenY)		/* Y-coordinate in text window that
    TCL_UNUSED(int))	/* Y-coordinate in text window that
				 * corresponds to y. */
{
    CharInfo *ciPtr = (CharInfo *)chunkPtr->clientData;
    const char *string;
    TextStyle *stylePtr;
    StyleValues *sValuePtr;
    int numBytes, offsetBytes, offsetX;
#if TK_DRAW_IN_CONTEXT
#ifdef TK_DRAW_IN_CONTEXT
    BaseCharInfo *bciPtr;
#endif /* TK_DRAW_IN_CONTEXT */
    (void)textPtr;
    (void)height;
    (void)screenY;

    if ((x + chunkPtr->width) <= 0) {
	/*
	 * The chunk is off-screen.
	 */

	return;
    }

#if TK_DRAW_IN_CONTEXT
#ifdef TK_DRAW_IN_CONTEXT
    bciPtr = ciPtr->baseChunkPtr->clientData;
    numBytes = Tcl_DStringLength(&bciPtr->baseChars);
    string = Tcl_DStringValue(&bciPtr->baseChars);

#elif TK_LAYOUT_WITH_BASE_CHUNKS
#elif defined(TK_LAYOUT_WITH_BASE_CHUNKS)
    if (ciPtr->baseChunkPtr != chunkPtr) {
	/*
	 * Without context drawing only base chunks display their foreground.
	 */

	return;
    }
8041
8042
8043
8044
8045
8046
8047
8048

8049
8050
8051
8052
8053
8054
8055
8029
8030
8031
8032
8033
8034
8035

8036
8037
8038
8039
8040
8041
8042
8043







-
+








    /*
     * Draw the text, underline, and overstrike for this chunk.
     */

    if (!sValuePtr->elide && (numBytes > offsetBytes)
	    && (stylePtr->fgGC != NULL)) {
#if TK_DRAW_IN_CONTEXT
#ifdef TK_DRAW_IN_CONTEXT
	int start = ciPtr->baseOffset + offsetBytes;
	int len = ciPtr->numBytes - offsetBytes;
	int xDisplacement = x - chunkPtr->x;

	if ((len > 0) && (string[start + len - 1] == '\t')) {
	    len--;
	}
8126
8127
8128
8129
8130
8131
8132
8133

8134
8135
8136
8137
8138
8139
8140

8141
8142
8143
8144
8145
8146
8147
8114
8115
8116
8117
8118
8119
8120

8121
8122
8123
8124

8125
8126

8127
8128
8129
8130
8131
8132
8133
8134







-
+



-


-
+







 *	Memory and other resources get freed.
 *
 *--------------------------------------------------------------
 */

static void
CharUndisplayProc(
    TkText *textPtr,		/* Overall information about text widget. */
    TCL_UNUSED(TkText *),	/* Overall information about text widget. */
    TkTextDispChunk *chunkPtr)	/* Chunk that is about to be freed. */
{
    CharInfo *ciPtr = (CharInfo *)chunkPtr->clientData;
    (void)textPtr;

    if (ciPtr) {
#if TK_LAYOUT_WITH_BASE_CHUNKS
#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
	if (chunkPtr == ciPtr->baseChunkPtr) {
	    /*
	     * Basechunks are undisplayed first, when DLines are freed or
	     * partially freed, so this makes sure we don't access their data
	     * any more.
	     */

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







-
+





-
+












-
-







 *	None.
 *
 *--------------------------------------------------------------
 */

static void
CharBboxProc(
    TkText *textPtr,
    TCL_UNUSED(TkText *),
    TkTextDispChunk *chunkPtr,	/* Chunk containing desired char. */
    int byteIndex,		/* Byte offset of desired character within the
				 * chunk. */
    int y,			/* Topmost pixel in area allocated for this
				 * line. */
    int lineHeight,		/* Height of line, in pixels. */
    TCL_UNUSED(int),	/* Height of line, in pixels. */
    int baseline,		/* Location of line's baseline, in pixels
				 * measured down from y. */
    int *xPtr, int *yPtr,	/* Gets filled in with coords of character's
				 * upper-left pixel. X-coord is in same
				 * coordinate system as chunkPtr->x. */
    int *widthPtr,		/* Gets filled in with width of character, in
				 * pixels. */
    int *heightPtr)		/* Gets filled in with height of character, in
				 * pixels. */
{
    CharInfo *ciPtr = (CharInfo *)chunkPtr->clientData;
    int maxX;
    (void)textPtr;
    (void)lineHeight;

    maxX = chunkPtr->width + chunkPtr->x;
    CharChunkMeasureChars(chunkPtr, NULL, 0, 0, byteIndex,
	    chunkPtr->x, -1, 0, xPtr);

    if (byteIndex == ciPtr->numBytes) {
	/*
8717
8718
8719
8720
8721
8722
8723
8724

8725
8726
8727
8728
8729
8730
8731
8702
8703
8704
8705
8706
8707
8708

8709
8710
8711
8712
8713
8714
8715
8716







-
+







	 * Special points at the next special character (or the end of the
	 * string). Process characters between start and special.
	 */

	if ((maxX >= 0) && (curX >= maxX)) {
	    break;
	}
#if TK_DRAW_IN_CONTEXT
#ifdef TK_DRAW_IN_CONTEXT
	start += TkpMeasureCharsInContext(tkfont, source, maxBytes,
		start - source, special - start,
		maxX >= 0 ? maxX - curX : -1, flags, &width);
#else
	(void) maxBytes;
	start += Tk_MeasureChars(tkfont, start, special - start,
		maxX >= 0 ? maxX - curX : -1, flags, &width);
8798
8799
8800
8801
8802
8803
8804

8805
8806
8807
8808
8809
8810
8811
8783
8784
8785
8786
8787
8788
8789
8790
8791
8792
8793
8794
8795
8796
8797







+







    static const char *const units[] = {
	"pages", "pixels", "units", NULL
    };
    enum viewUnits {
	VIEW_SCROLL_PAGES, VIEW_SCROLL_PIXELS, VIEW_SCROLL_UNITS
    };
    int index;
    double d;

    if (Tcl_GetIndexFromObjStruct(interp, objv[2], subcommands,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TKTEXT_SCROLL_ERROR;
    }

    switch ((enum viewSubcmds) index) {
8825
8826
8827
8828
8829
8830
8831
8832

8833




8834
8835
8836
8837
8838
8839
8840



8841
8842
8843

8844




8845
8846
8847
8848
8849
8850
8851
8852
8853

8854
8855
8856
8857
8858
8859
8860
8811
8812
8813
8814
8815
8816
8817

8818
8819
8820
8821
8822
8823
8824
8825
8826
8827
8828
8829
8830
8831
8832
8833
8834
8835

8836
8837
8838
8839
8840
8841
8842
8843
8844
8845
8846
8847
8848
8849

8850
8851
8852
8853
8854
8855
8856
8857







-
+

+
+
+
+







+
+
+


-
+

+
+
+
+








-
+







	}
	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_GetIntFromObj(interp, objv[3], intPtr) != TCL_OK) {
	    if (Tcl_GetDoubleFromObj(interp, objv[3], &d) != TCL_OK) {
		return TKTEXT_SCROLL_ERROR;
	    }
	    *intPtr = (d > 0) ? ceil(d) : floor(d);
	    if (dblPtr) {
		*dblPtr = d;
	    }
	    return TKTEXT_SCROLL_PAGES;
	case VIEW_SCROLL_PIXELS:
	    if (Tk_GetPixelsFromObj(interp, textPtr->tkwin, objv[3],
		    intPtr) != TCL_OK) {
		return TKTEXT_SCROLL_ERROR;
	    }
	    if (dblPtr) {
		*dblPtr = (double)*intPtr;
	    }
	    return TKTEXT_SCROLL_PIXELS;
	case VIEW_SCROLL_UNITS:
	    if (Tcl_GetIntFromObj(interp, objv[3], intPtr) != TCL_OK) {
	    if (Tcl_GetDoubleFromObj(interp, objv[3], &d) != TCL_OK) {
		return TKTEXT_SCROLL_ERROR;
	    }
	    *intPtr = (d > 0) ? ceil(d) : floor(d);
	    if (dblPtr) {
		*dblPtr = d;
	    }
	    return TKTEXT_SCROLL_UNITS;
	}
    }
    Tcl_Panic("unexpected switch fallthrough");
    return TKTEXT_SCROLL_ERROR;
}

#if TK_LAYOUT_WITH_BASE_CHUNKS
#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
/*
 *----------------------------------------------------------------------
 *
 * FinalizeBaseChunk --
 *
 *	This procedure makes sure that all the chunks of the stretch are
 *	up-to-date. It is invoked when the LayoutProc has been called for all
8877
8878
8879
8880
8881
8882
8883
8884

8885
8886
8887
8888
8889
8890
8891
8892
8893
8894
8895
8896
8897
8898

8899
8900
8901
8902
8903
8904
8905
8906
8907
8908
8909
8910
8911

8912
8913
8914
8915
8916
8917
8918
8919
8920
8921
8922
8923
8924
8925

8926
8927
8928
8929
8930
8931
8932
8874
8875
8876
8877
8878
8879
8880

8881
8882
8883
8884
8885
8886
8887
8888
8889
8890
8891
8892
8893
8894

8895
8896
8897
8898
8899
8900
8901
8902
8903
8904
8905
8906
8907

8908
8909
8910
8911
8912
8913
8914
8915
8916
8917
8918
8919
8920
8921

8922
8923
8924
8925
8926
8927
8928
8929







-
+













-
+












-
+













-
+







				 * even though it may not be in the linked
				 * list yet. Used by the LayoutProc, otherwise
				 * NULL. */
{
    const char *baseChars;
    TkTextDispChunk *chunkPtr;
    CharInfo *ciPtr;
#if TK_DRAW_IN_CONTEXT
#ifdef TK_DRAW_IN_CONTEXT
    int widthAdjust = 0;
    int newwidth;
#endif /* TK_DRAW_IN_CONTEXT */

    if (baseCharChunkPtr == NULL) {
	return;
    }

    baseChars = Tcl_DStringValue(
	    &((BaseCharInfo *) baseCharChunkPtr->clientData)->baseChars);

    for (chunkPtr = baseCharChunkPtr; chunkPtr != NULL;
	    chunkPtr = chunkPtr->nextPtr) {
#if TK_DRAW_IN_CONTEXT
#ifdef TK_DRAW_IN_CONTEXT
	chunkPtr->x += widthAdjust;
#endif /* TK_DRAW_IN_CONTEXT */

	if (chunkPtr->displayProc != CharDisplayProc) {
	    continue;
	}
	ciPtr = chunkPtr->clientData;
	if (ciPtr->baseChunkPtr != baseCharChunkPtr) {
	    break;
	}
	ciPtr->chars = baseChars + ciPtr->baseOffset;

#if TK_DRAW_IN_CONTEXT
#ifdef TK_DRAW_IN_CONTEXT
	newwidth = 0;
	CharChunkMeasureChars(chunkPtr, NULL, 0, 0, -1, 0, -1, 0, &newwidth);
	if (newwidth < chunkPtr->width) {
	    widthAdjust += newwidth - chunkPtr->width;
	    chunkPtr->width = newwidth;
	}
#endif /* TK_DRAW_IN_CONTEXT */
    }

    if (addChunkPtr != NULL) {
	ciPtr = addChunkPtr->clientData;
	ciPtr->chars = baseChars + ciPtr->baseOffset;

#if TK_DRAW_IN_CONTEXT
#ifdef TK_DRAW_IN_CONTEXT
	addChunkPtr->x += widthAdjust;
	CharChunkMeasureChars(addChunkPtr, NULL, 0, 0, -1, 0, -1, 0,
		&addChunkPtr->width);
#endif /* TK_DRAW_IN_CONTEXT */
    }

    baseCharChunkPtr = NULL;
9016
9017
9018
9019
9020
9021
9022
9023

9024
9025
9026
9027
9028
9029
9030
9031
9032
9033
9034
9035
9036
9037
9038
9039

9040
9041
9042
9043
9044
9045
9046
9013
9014
9015
9016
9017
9018
9019

9020
9021
9022
9023
9024
9025
9026
9027
9028
9029
9030
9031
9032
9033
9034
9035

9036
9037
9038
9039
9040
9041
9042
9043







-
+















-
+







    StyleValues *sv1;
    StyleValues *sv2;

    if (style1 == style2) {
	return 1;
    }

#if !TK_DRAW_IN_CONTEXT
#if !defined(TK_DRAW_IN_CONTEXT)
    if (
#ifdef MAC_OSX_TK
	    !TkMacOSXCompareColors(style1->fgGC->foreground,
		    style2->fgGC->foreground)
#else
	    style1->fgGC->foreground != style2->fgGC->foreground
#endif
	    ) {
	return 0;
    }
#endif /* !TK_DRAW_IN_CONTEXT */

    sv1 = style1->sValuePtr;
    sv2 = style2->sValuePtr;

#if TK_DRAW_IN_CONTEXT
#ifdef TK_DRAW_IN_CONTEXT
    return sv1->tkfont == sv2->tkfont && sv1->offset == sv2->offset;
#else
    return sv1->tkfont == sv2->tkfont
	    && sv1->underline == sv2->underline
	    && sv1->overstrike == sv2->overstrike
	    && sv1->elide == sv2->elide
	    && sv1->offset == sv2->offset

Changes to generic/tkTextImage.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






-
+







/*
 * tkImage.c --
 *
 *	This file contains code that allows images to be nested inside text
 *	widgets. It also implements the "image" widget command for texts.
 *
 * Copyright (c) 1997 Sun Microsystems, Inc.
 * Copyright © 1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkPort.h"
#include "tkText.h"
286
287
288
289
290
291
292



293
294



295
296
297
298
299
300
301
286
287
288
289
290
291
292
293
294
295


296
297
298
299
300
301
302
303
304
305







+
+
+
-
-
+
+
+







	resultObj = Tcl_NewObj();
	for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->imageTable,
		&search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    (const char *)Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, hPtr),
		    -1));
	}
	if (resultObj == NULL) {
	    return TCL_ERROR;
	} else {
	Tcl_SetObjResult(interp, resultObj);
	return TCL_OK;
	    Tcl_SetObjResult(interp, resultObj);
	    return TCL_OK;
	}
    }
    default:
	Tcl_Panic("unexpected switch fallthrough");
    }
    return TCL_ERROR;
}

443
444
445
446
447
448
449
450
451


452
453
454
455
456
457
458
459
460
461
462
463
464
447
448
449
450
451
452
453


454
455
456
457
458
459


460
461
462
463
464
465
466







-
-
+
+




-
-







 *
 *--------------------------------------------------------------
 */

static int
EmbImageDeleteProc(
    TkTextSegment *eiPtr,	/* Segment being deleted. */
    TkTextLine *linePtr,	/* Line containing segment. */
    int treeGone)		/* Non-zero means the entire tree is being
    TCL_UNUSED(TkTextLine *),	/* Line containing segment. */
    TCL_UNUSED(int))		/* Non-zero means the entire tree is being
				 * deleted, so everything must get cleaned
				 * up. */
{
    Tcl_HashEntry *hPtr;
    (void)linePtr;
    (void)treeGone;

    if (eiPtr->body.ei.image != NULL) {
	hPtr = Tcl_FindHashEntry(&eiPtr->body.ei.sharedTextPtr->imageTable,
		eiPtr->body.ei.name);
	if (hPtr != NULL) {
	    /*
	     * (It's possible for there to be no hash table entry for this
527
528
529
530
531
532
533
534

535
536
537
538
539
540

541
542
543
544

545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
529
530
531
532
533
534
535

536
537
538
539
540
541

542
543
544
545

546
547
548
549
550
551
552
553
554



555
556
557
558
559
560
561







-
+





-
+



-
+








-
-
-







 *
 *--------------------------------------------------------------
 */

static int
EmbImageLayoutProc(
    TkText *textPtr,		/* Text widget being layed out. */
    TkTextIndex *indexPtr,	/* Identifies first character in chunk. */
    TCL_UNUSED(TkTextIndex *),	/* Identifies first character in chunk. */
    TkTextSegment *eiPtr,	/* Segment corresponding to indexPtr. */
    TkSizeT offset,			/* Offset within segPtr corresponding to
				 * indexPtr (always 0). */
    int maxX,			/* Chunk must not occupy pixels at this
				 * position or higher. */
    TkSizeT maxChars,		/* Chunk must not include more than this many
    TCL_UNUSED(TkSizeT),	/* Chunk must not include more than this many
				 * characters. */
    int noCharsYet,		/* Non-zero means no characters have been
				 * assigned to this line yet. */
    TkWrapMode wrapMode,	/* Wrap mode to use for line:
    TCL_UNUSED(TkWrapMode),	/* Wrap mode to use for line:
				 * TEXT_WRAPMODE_CHAR, TEXT_WRAPMODE_NONE, or
				 * TEXT_WRAPMODE_WORD. */
    TkTextDispChunk *chunkPtr)
				/* Structure to fill in with information about
				 * this chunk. The x field has already been
				 * set by the caller. */
{
    int width, height;
    (void)indexPtr;
    (void)maxChars;
    (void)wrapMode;

    if (offset != 0) {
	Tcl_Panic("Non-zero offset in EmbImageLayoutProc");
    }

    /*
     * See if there's room for this image on this line.
618
619
620
621
622
623
624
625

626
627
628
629
630
631
632
633
634
635
617
618
619
620
621
622
623

624
625


626
627
628
629
630
631
632







-
+

-
-







 *
 *--------------------------------------------------------------
 */

static void
EmbImageCheckProc(
    TkTextSegment *eiPtr,	/* Segment to check. */
    TkTextLine *linePtr)	/* Line containing segment. */
    TCL_UNUSED(TkTextLine *))	/* Line containing segment. */
{
    (void)linePtr;

    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);
    }
661
662
663
664
665
666
667
668

669
670

671
672
673
674
675
676
677
678
679
680
681
682
683
684
658
659
660
661
662
663
664

665
666

667
668
669
670
671
672


673
674
675
676
677
678
679







-
+

-
+





-
-







				 * chunk (differs from the x-position in the
				 * chunk because of scrolling). */
    int y,			/* Top of rectangular bounding box for line:
				 * tells where to draw this chunk in dst
				 * (x-position is in the chunk itself). */
    int lineHeight,		/* Total height of line. */
    int baseline,		/* Offset of baseline from y. */
    Display *display,		/* Display to use for drawing. */
    TCL_UNUSED(Display *),	/* Display to use for drawing. */
    Drawable dst,		/* Pixmap or window in which to draw */
    int screenY)		/* Y-coordinate in text window that
    TCL_UNUSED(int))	/* Y-coordinate in text window that
				 * corresponds to y. */
{
    TkTextSegment *eiPtr = (TkTextSegment *)chunkPtr->clientData;
    int lineX, imageX, imageY, width, height;
    Tk_Image image;
    (void)display;
    (void)screenY;

    image = eiPtr->body.ei.image;
    if (image == NULL) {
	return;
    }
    if ((x + chunkPtr->width) <= 0) {
	return;
716
717
718
719
720
721
722
723

724
725

726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
711
712
713
714
715
716
717

718
719

720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735


736
737
738
739
740
741
742







-
+

-
+















-
-







 *	None.
 *
 *--------------------------------------------------------------
 */

static void
EmbImageBboxProc(
    TkText *textPtr,
    TCL_UNUSED(TkText *),
    TkTextDispChunk *chunkPtr,	/* Chunk containing desired char. */
    int index,			/* Index of desired character within the
    TCL_UNUSED(int),			/* Index of desired character within the
				 * chunk. */
    int y,			/* Topmost pixel in area allocated for this
				 * line. */
    int lineHeight,		/* Total height of line. */
    int baseline,		/* Location of line's baseline, in pixels
				 * measured down from y. */
    int *xPtr, int *yPtr,	/* Gets filled in with coords of character's
				 * upper-left pixel. */
    int *widthPtr,		/* Gets filled in with width of image, in
				 * pixels. */
    int *heightPtr)		/* Gets filled in with height of image, in
				 * pixels. */
{
    TkTextSegment *eiPtr = (TkTextSegment *)chunkPtr->clientData;
    Tk_Image image;
    (void)textPtr;
    (void)index;

    image = eiPtr->body.ei.image;
    if (image != NULL) {
	Tk_SizeOfImage(image, widthPtr, heightPtr);
    } else {
	*widthPtr = 0;
	*heightPtr = 0;
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
819
820
821
822
823
824
825

826
827
828

829
830
831

832
833
834
835
836
837






838
839
840
841
842
843
844







-
+

+
-
+

+
-
+
+




-
-
-
-
-
-







 *
 *--------------------------------------------------------------
 */

static void
EmbImageProc(
    ClientData clientData,	/* Pointer to widget record. */
    int x, int y,		/* Upper left pixel (within image) that must
    TCL_UNUSED(int),		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    TCL_UNUSED(int),
    int width, int height,	/* Dimensions of area to redisplay (may be
    TCL_UNUSED(int),	/* Dimensions of area to redisplay (may be
				 * <= 0). */
    TCL_UNUSED(int),
    int imgWidth, int imgHeight)/* New dimensions of image. */
    TCL_UNUSED(int),/* New dimensions of image. */
    TCL_UNUSED(int))

{
    TkTextSegment *eiPtr = (TkTextSegment *)clientData;
    TkTextIndex index;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)imgWidth;
    (void)imgHeight;

    index.tree = eiPtr->body.ei.sharedTextPtr->tree;
    index.linePtr = eiPtr->body.ei.linePtr;
    index.byteIndex = TkTextSegToOffset(eiPtr, eiPtr->body.ei.linePtr);
    TkTextChanged(eiPtr->body.ei.sharedTextPtr, NULL, &index, &index);

    /*

Changes to generic/tkTextIndex.c.

1
2
3
4
5
6
7
8


9
10
11
12
13
14
15
1
2
3
4
5
6


7
8
9
10
11
12
13
14
15






-
-
+
+







/*
 * tkTextIndex.c --
 *
 *	This module provides functions that manipulate indices for text
 *	widgets.
 *
 * Copyright (c) 1992-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright  © 1992-1994 The Regents of the University of California.
 * Copyright  © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkText.h"
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







-
+







 */

#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))
	((objPtr)->internalRep.twoPtrValue.ptr1 = (void *)(indexPtr))
#define SET_INDEXEPOCH(objPtr, epoch) \
	((objPtr)->internalRep.twoPtrValue.ptr2 = (void *) (size_t) (epoch))

/*
 * Define the 'textindex' object type, which Tk uses to represent indices in
 * text widgets internally.
 */

Changes to generic/tkTextMark.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






-
-
+
+







/*
 * tkTextMark.c --
 *
 *	This file contains the functions that implement marks for text
 *	widgets.
 *
 * Copyright (c) 1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkText.h"
129
130
131
132
133
134
135
136

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

136
137
138
139
140
141
142
143







-
+







	TkSizeT length;
	const char *str;

	if (objc < 4 || objc > 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "markName ?gravity?");
	    return TCL_ERROR;
	}
	str = TkGetStringFromObj(objv[3], &length);
	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 {
497
498
499
500
501
502
503
504
505
506



507
508
509
510
511
512
513
514
515
516
517
518
519
520
497
498
499
500
501
502
503



504
505
506
507
508
509




510
511
512
513
514
515
516







-
-
-
+
+
+



-
-
-
-







 *	mark; it will be done elsewhere).
 *
 *--------------------------------------------------------------
 */

static int
MarkDeleteProc(
    TkTextSegment *segPtr,	/* Segment being deleted. */
    TkTextLine *linePtr,	/* Line containing segment. */
    int treeGone)		/* Non-zero means the entire tree is being
    TCL_UNUSED(TkTextSegment *),	/* Segment being deleted. */
    TCL_UNUSED(TkTextLine *),	/* Line containing segment. */
    TCL_UNUSED(int))		/* Non-zero means the entire tree is being
				 * deleted, so everything must get cleaned
				 * up. */
{
    (void)segPtr;
    (void)linePtr;
    (void)treeGone;

    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * MarkCleanupProc --
558
559
560
561
562
563
564
565

566
567

568
569

570
571

572
573

574
575

576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
554
555
556
557
558
559
560

561
562

563
564

565
566

567
568

569
570

571
572
573
574
575
576







577
578
579
580
581
582
583







-
+

-
+

-
+

-
+

-
+

-
+





-
-
-
-
-
-
-







 *
 *--------------------------------------------------------------
 */

static int
MarkLayoutProc(
    TkText *textPtr,		/* Text widget being layed out. */
    TkTextIndex *indexPtr,	/* Identifies first character in chunk. */
    TCL_UNUSED(TkTextIndex *),	/* Identifies first character in chunk. */
    TkTextSegment *segPtr,	/* Segment corresponding to indexPtr. */
    TkSizeT offset,			/* Offset within segPtr corresponding to
    TCL_UNUSED(TkSizeT),		/* Offset within segPtr corresponding to
				 * indexPtr (always 0). */
    int maxX,			/* Chunk must not occupy pixels at this
    TCL_UNUSED(int),			/* Chunk must not occupy pixels at this
				 * position or higher. */
    TkSizeT maxChars,		/* Chunk must not include more than this many
    TCL_UNUSED(TkSizeT),		/* Chunk must not include more than this many
				 * characters. */
    int noCharsYet,		/* Non-zero means no characters have been
    TCL_UNUSED(int),		/* Non-zero means no characters have been
				 * assigned to this line yet. */
    TkWrapMode wrapMode,	/* Not used. */
    TCL_UNUSED(TkWrapMode),	/* Not used. */
    TkTextDispChunk *chunkPtr)
				/* Structure to fill in with information about
				 * this chunk. The x field has already been
				 * set by the caller. */
{
    (void)indexPtr;
    (void)offset;
    (void)maxX;
    (void)maxChars;
    (void)noCharsYet;
    (void)wrapMode;

    if (segPtr != textPtr->insertMarkPtr) {
	return -1;
    }

    chunkPtr->displayProc = TkTextInsertDisplayProc;
    chunkPtr->undisplayProc = InsertUndisplayProc;
    chunkPtr->measureProc = NULL;
624
625
626
627
628
629
630
631

632
633
634
635
636
637
638
639


640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
613
614
615
616
617
618
619

620
621
622
623
624
625
626


627
628
629
630
631
632
633
634
635
636
637
638
639
640
641



642
643
644
645
646
647
648







-
+






-
-
+
+













-
-
-







 *
 *--------------------------------------------------------------
 */

void
TkTextInsertDisplayProc(
    TkText *textPtr,		/* The current text widget. */
    TkTextDispChunk *chunkPtr,	/* Chunk that is to be drawn. */
    TCL_UNUSED(TkTextDispChunk *),	/* Chunk that is to be drawn. */
    int x,			/* X-position in dst at which to draw this
				 * chunk (may differ from the x-position in
				 * the chunk because of scrolling). */
    int y,			/* Y-position at which to draw this chunk in
				 * dst (x-position is in the chunk itself). */
    int height,			/* Total height of line. */
    int baseline,		/* Offset of baseline from y. */
    Display *display,		/* Display to use for drawing. */
    TCL_UNUSED(int),		/* Offset of baseline from y. */
    TCL_UNUSED(Display *),		/* Display to use for drawing. */
    Drawable dst,		/* Pixmap or window in which to draw chunk. */
    int screenY)		/* Y-coordinate in text window that
				 * corresponds to y. */
{
    /*
     * We have no need for the clientData.
     */

    /* TkText *textPtr = chunkPtr->clientData; */
    TkTextIndex index;
    int halfWidth = textPtr->insertWidth/2;
    int rightSideWidth;
    int ix = 0, iy = 0, iw = 0, ih = 0, charWidth = 0;
    (void)chunkPtr;
    (void)baseline;
    (void)display;

    if (textPtr->insertCursorType) {
	TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);
	TkTextIndexBbox(textPtr, &index, &ix, &iy, &iw, &ih, &charWidth);
	rightSideWidth = charWidth + halfWidth;
    } else {
	rightSideWidth = halfWidth;
731
732
733
734
735
736
737
738
739


740
741
742
743
744
745
746
747
748
749
750
717
718
719
720
721
722
723


724
725
726



727
728
729
730
731
732
733







-
-
+
+

-
-
-







 *	None.
 *
 *--------------------------------------------------------------
 */

static void
InsertUndisplayProc(
    TkText *textPtr,		/* Overall information about text widget. */
    TkTextDispChunk *chunkPtr)	/* Chunk that is about to be freed. */
    TCL_UNUSED(TkText *),		/* Overall information about text widget. */
    TCL_UNUSED(TkTextDispChunk *))	/* Chunk that is about to be freed. */
{
    (void)textPtr;
    (void)chunkPtr;

    return;
}

/*
 *--------------------------------------------------------------
 *
 * MarkCheckProc --

Changes to generic/tkTextTag.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







-
-
+
+







/*
 * tkTextTag.c --
 *
 *	This module implements the "tag" subcommand of the widget command for
 *	text widgets, plus most of the other high-level functions related to
 *	tags.
 *
 * Copyright (c) 1992-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1992-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkText.h"
353
354
355
356
357
358
359
360

361
362
363
364
365
366
367
353
354
355
356
357
358
359

360
361
362
363
364
365
366
367







-
+







	}
	break;
    case TAG_CONFIGURE: {
	int newTag;

	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 3, objv,
		    "tagName ?-option? ?value? ?-option value ...?");
		    "tagName ?-option value ...?");
	    return TCL_ERROR;
	}
	tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), &newTag);
	if (objc <= 5) {
	    Tcl_Obj *objPtr = Tk_GetOptionInfo(interp, tagPtr,
		    tagPtr->optionTable,
		    (objc == 5) ? objv[4] : NULL, textPtr->tkwin);
1107
1108
1109
1110
1111
1112
1113
1114

1115
1116
1117
1118
1119
1120
1121
1107
1108
1109
1110
1111
1112
1113

1114
1115
1116
1117
1118
1119
1120
1121







-
+







    TkText *textPtr,		/* Widget in which tag is being used. */
    Tcl_Obj *tagName)		/* Name of desired tag. */
{
    Tcl_HashEntry *hPtr;
    TkSizeT len;
    const char *str;

    str = TkGetStringFromObj(tagName, &len);
    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);
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
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







-
+


















-
+







 *	any).
 *
 *--------------------------------------------------------------
 */

void
TkTextBindProc(
    ClientData clientData,	/* Pointer to canvas structure. */
    ClientData clientData,	/* Pointer to text widget structure. */
    XEvent *eventPtr)		/* Pointer to X event that just happened. */
{
    TkText *textPtr = (TkText *)clientData;
    int repick = 0;

    textPtr->refCount++;

    /*
     * This code simulates grabs for mouse buttons by keeping track of whether
     * a button is pressed and refusing to pick a new current character while
     * a button is pressed.
     */

    if (eventPtr->type == ButtonPress) {
	textPtr->flags |= BUTTON_DOWN;
    } else if (eventPtr->type == ButtonRelease) {
	unsigned long mask;

	mask = TkGetButtonMask(eventPtr->xbutton.button);
	mask = Tk_GetButtonMask(eventPtr->xbutton.button);
	if ((eventPtr->xbutton.state & ALL_BUTTONS) == mask) {
	    textPtr->flags &= ~BUTTON_DOWN;
	    repick = 1;
	}
    } else if ((eventPtr->type == EnterNotify)
	    || (eventPtr->type == LeaveNotify)) {
	if (eventPtr->xcrossing.state & ALL_BUTTONS) {

Changes to generic/tkTextWind.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
1
2
3
4
5
6
7


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

25
26
27
28
29
30

31
32
33
34
35
36
37
38







-
-
+
+















-
+





-
+







/*
 * tkTextWind.c --
 *
 *	This file contains code that allows arbitrary windows to be nested
 *	inside text widgets. It also implements the "window" widget command
 *	for texts.
 *
 * Copyright (c) 1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkPort.h"
#include "tkText.h"

/*
 * The following structure is the official type record for the embedded window
 * geometry manager:
 */

static void		EmbWinRequestProc(ClientData clientData,
			    Tk_Window tkwin);
static void		EmbWinLostSlaveProc(ClientData clientData,
static void		EmbWinLostContentProc(ClientData clientData,
			    Tk_Window tkwin);

static const Tk_GeomMgr textGeomType = {
    "text",			/* name */
    EmbWinRequestProc,		/* requestProc */
    EmbWinLostSlaveProc,	/* lostSlaveProc */
    EmbWinLostContentProc,	/* lostContentProc */
};

/*
 * Macro that determines the size of an embedded window segment:
 */

#define EW_SEG_SIZE (offsetof(TkTextSegment, body) \
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







-







    if (Tcl_GetIndexFromObjStruct(interp, objv[2], windOptionStrings,
	    sizeof(char *), "window option", 0, &optionIndex) != TCL_OK) {
	return TCL_ERROR;
    }
    switch ((enum windOptions) optionIndex) {
    case WIND_CGET: {
	TkTextIndex index;
	TkTextSegment *ewPtr;
	Tcl_Obj *objPtr;
	TkTextEmbWindowClient *client;

	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index option");
	    return TCL_ERROR;
	}
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







-







	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, objPtr);
	return TCL_OK;
    }
    case WIND_CONFIGURE: {
	TkTextIndex index;
	TkTextSegment *ewPtr;

	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index ?-option value ...?");
	    return TCL_ERROR;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
	    return TCL_ERROR;
439
440
441
442
443
444
445
446

447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462

463
464
465
466
467
468
469
437
438
439
440
441
442
443

444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459

460
461
462
463
464
465
466
467







-
+















-
+








	    parent = Tk_Parent(ewPtr->body.ew.tkwin);
	    for (ancestor = textPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
		if (ancestor == parent) {
		    break;
		}
		if (Tk_TopWinHierarchy(ancestor)) {
		badMaster:
		badContainer:
		    Tcl_SetObjResult(textPtr->interp, Tcl_ObjPrintf(
			    "can't embed %s in %s",
			    Tk_PathName(ewPtr->body.ew.tkwin),
			    Tk_PathName(textPtr->tkwin)));
		    Tcl_SetErrorCode(textPtr->interp, "TK", "GEOMETRY",
			    "HIERARCHY", NULL);
		    ewPtr->body.ew.tkwin = NULL;
		    if (client != NULL) {
			client->tkwin = NULL;
		    }
		    return TCL_ERROR;
		}
	    }
	    if (Tk_TopWinHierarchy(ewPtr->body.ew.tkwin)
		    || (ewPtr->body.ew.tkwin == textPtr->tkwin)) {
		goto badMaster;
		goto badContainer;
	    }

	    if (client == NULL) {
		/*
		 * Have to make the new client.
		 */

572
573
574
575
576
577
578
579

580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597

598
599

600
601
602
603
604
605
606
607
608
609
610
611
612
613
614

615
616
617
618
619
620
621
570
571
572
573
574
575
576

577
578
579
580
581

582
583
584
585
586
587
588
589
590
591
592
593

594
595

596
597
598
599
600
601
602
603
604
605
606
607
608
609
610

611
612
613
614
615
616
617
618







-
+




-












-
+

-
+














-
+







 *
 *--------------------------------------------------------------
 */

static void
EmbWinRequestProc(
    ClientData clientData,	/* Pointer to record for window item. */
    Tk_Window tkwin)		/* 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;
    (void)tkwin;

    index.tree = ewPtr->body.ew.sharedTextPtr->tree;
    index.linePtr = ewPtr->body.ew.linePtr;
    index.byteIndex = TkTextSegToOffset(ewPtr, ewPtr->body.ew.linePtr);
    TkTextChanged(ewPtr->body.ew.sharedTextPtr, NULL, &index, &index);
    TkTextInvalidateLineMetrics(ewPtr->body.ew.sharedTextPtr, NULL,
	    index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinLostSlaveProc --
 * EmbWinLostContentProc --
 *
 *	This function is invoked by the Tk geometry manager when a slave
 *	This function is invoked by the Tk geometry manager when a content
 *	window managed by a text widget is claimed away by another geometry
 *	manager.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The window is disassociated from the window segment, and the portion
 *	of the text is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
EmbWinLostSlaveProc(
EmbWinLostContentProc(
    ClientData clientData,	/* Pointer to record describing window item. */
    Tk_Window tkwin)		/* Window that was claimed away by another
				 * geometry manager. */
{
    TkTextEmbWindowClient *client = (TkTextEmbWindowClient *)clientData;
    TkTextSegment *ewPtr = client->parent;
    TkTextIndex index;
735
736
737
738
739
740
741
742
743


744
745
746
747
748
749
750
751
752
753
754
755
756
757
732
733
734
735
736
737
738


739
740
741
742
743
744
745


746
747
748
749
750
751
752







-
-
+
+





-
-







 *
 *--------------------------------------------------------------
 */

static int
EmbWinDeleteProc(
    TkTextSegment *ewPtr,	/* Segment being deleted. */
    TkTextLine *linePtr,	/* Line containing segment. */
    int treeGone)		/* Non-zero means the entire tree is being
    TCL_UNUSED(TkTextLine *),	/* Line containing segment. */
    TCL_UNUSED(int))		/* Non-zero means the entire tree is being
				 * deleted, so everything must get cleaned
				 * up. */
{
    TkTextEmbWindowClient *client;
    client = ewPtr->body.ew.clients;
    (void)linePtr;
    (void)treeGone;

    while (client != NULL) {
	TkTextEmbWindowClient *next = client->next;
	Tcl_HashEntry *hPtr = NULL;

	if (client->tkwin != NULL) {
	    hPtr = Tcl_FindHashEntry(
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
811
812
813
814
815
816
817

818
819
820
821
822
823

824
825
826
827

828
829
830
831
832
833
834
835
836
837



838
839
840
841
842
843
844







-
+





-
+



-
+









-
-
-







 *
 *--------------------------------------------------------------
 */

static int
EmbWinLayoutProc(
    TkText *textPtr,		/* Text widget being layed out. */
    TkTextIndex *indexPtr,	/* Identifies first character in chunk. */
    TCL_UNUSED(TkTextIndex *),	/* Identifies first character in chunk. */
    TkTextSegment *ewPtr,	/* Segment corresponding to indexPtr. */
    TkSizeT offset,			/* Offset within segPtr corresponding to
				 * indexPtr (always 0). */
    int maxX,			/* Chunk must not occupy pixels at this
				 * position or higher. */
    TkSizeT maxChars,		/* Chunk must not include more than this many
    TCL_UNUSED(TkSizeT),	/* Chunk must not include more than this many
				 * characters. */
    int noCharsYet,		/* Non-zero means no characters have been
				 * assigned to this line yet. */
    TkWrapMode wrapMode,	/* Wrap mode to use for line:
    TCL_UNUSED(TkWrapMode),	/* Wrap mode to use for line:
				 * TEXT_WRAPMODE_CHAR, TEXT_WRAPMODE_NONE, or
				 * TEXT_WRAPMODE_WORD. */
    TkTextDispChunk *chunkPtr)
				/* Structure to fill in with information about
				 * this chunk. The x field has already been
				 * set by the caller. */
{
    int width, height;
    TkTextEmbWindowClient *client;
    (void)indexPtr;
    (void)maxChars;
    (void)wrapMode;

    if (offset != 0) {
	Tcl_Panic("Non-zero offset in EmbWinLayoutProc");
    }

    client = EmbWinGetClient(textPtr, ewPtr);
    if (client == NULL) {
935
936
937
938
939
940
941
942

943
944
945
946
947

948
949
950
951
952
953
954
927
928
929
930
931
932
933

934
935
936
937
938

939
940
941
942
943
944
945
946







-
+




-
+







	}

	for (ancestor = textPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == Tk_Parent(ewPtr->body.ew.tkwin)) {
		break;
	    }
	    if (Tk_TopWinHierarchy(ancestor)) {
		goto badMaster;
		goto badContainer;
	    }
	}
	if (Tk_TopWinHierarchy(ewPtr->body.ew.tkwin)
		|| (textPtr->tkwin == ewPtr->body.ew.tkwin)) {
	badMaster:
	badContainer:
	    Tcl_SetObjResult(textPtr->interp, Tcl_ObjPrintf(
		    "can't embed %s relative to %s",
		    Tk_PathName(ewPtr->body.ew.tkwin),
		    Tk_PathName(textPtr->tkwin)));
	    Tcl_SetErrorCode(textPtr->interp, "TK", "GEOMETRY", "HIERARCHY",
		    NULL);
	    Tcl_BackgroundException(textPtr->interp, TCL_ERROR);
1051
1052
1053
1054
1055
1056
1057
1058

1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1043
1044
1045
1046
1047
1048
1049

1050
1051


1052
1053
1054
1055
1056
1057
1058







-
+

-
-







 *
 *--------------------------------------------------------------
 */

static void
EmbWinCheckProc(
    TkTextSegment *ewPtr,	/* Segment to check. */
    TkTextLine *linePtr)	/* Line containing segment. */
    TCL_UNUSED(TkTextLine *))	/* Line containing segment. */
{
    (void)linePtr;

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







-
+




-
-
+
+








-
-
-







void
TkTextEmbWinDisplayProc(
    TkText *textPtr,		/* Information about text widget. */
    TkTextDispChunk *chunkPtr,	/* Chunk that is to be drawn. */
    int x,			/* X-position in dst at which to draw this
				 * chunk (differs from the x-position in the
				 * chunk because of scrolling). */
    int y,			/* Top of rectangular bounding box for line:
    TCL_UNUSED(int),	/* Top of rectangular bounding box for line:
				 * tells where to draw this chunk in dst
				 * (x-position is in the chunk itself). */
    int lineHeight,		/* Total height of line. */
    int baseline,		/* Offset of baseline from y. */
    Display *display,		/* Display to use for drawing (unused).  */
    Drawable dst,		/* Pixmap or window in which to draw
    TCL_UNUSED(Display *),	/* Display to use for drawing (unused).  */
    TCL_UNUSED(Drawable),	/* Pixmap or window in which to draw
				 * (unused).  */
    int screenY)		/* Y-coordinate in text window that
				 * corresponds to y. */
{
    int lineX, windowX, windowY, width, height;
    Tk_Window tkwin;
    TkTextSegment *ewPtr = (TkTextSegment *)chunkPtr->clientData;
    TkTextEmbWindowClient *client = EmbWinGetClient(textPtr, ewPtr);
    (void)y;
    (void)display;
    (void)dst;

    if (client == NULL) {
	return;
    }

    tkwin = client->tkwin;
    if (tkwin == NULL) {
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
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







-
+
















-







 *--------------------------------------------------------------
 */

static void
EmbWinBboxProc(
    TkText *textPtr,		/* Information about text widget. */
    TkTextDispChunk *chunkPtr,	/* Chunk containing desired char. */
    int index,			/* Index of desired character within the
    TCL_UNUSED(int),			/* Index of desired character within the
				 * chunk. */
    int y,			/* Topmost pixel in area allocated for this
				 * line. */
    int lineHeight,		/* Total height of line. */
    int baseline,		/* Location of line's baseline, in pixels
				 * measured down from y. */
    int *xPtr, int *yPtr,	/* Gets filled in with coords of character's
				 * upper-left pixel. */
    int *widthPtr,		/* Gets filled in with width of window, in
				 * pixels. */
    int *heightPtr)		/* Gets filled in with height of window, in
				 * pixels. */
{
    Tk_Window tkwin;
    TkTextSegment *ewPtr = (TkTextSegment *)chunkPtr->clientData;
    TkTextEmbWindowClient *client = EmbWinGetClient(textPtr, ewPtr);
    (void)index;

    if (client == NULL) {
	tkwin = NULL;
    } else {
	tkwin = client->tkwin;
    }
    if (tkwin != NULL) {

Changes to generic/tkTrig.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







-
-
+
+







/*
 * tkTrig.c --
 *
 *	This file contains a collection of trigonometry utility routines that
 *	are used by Tk and in particular by the canvas code. It also has
 *	miscellaneous geometry functions used by canvases.
 *
 * Copyright (c) 1992-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1992-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkCanvas.h"

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 © 2002 Ludwig Callewaert.
 * Copyright © 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/tkUndo.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





-
+







/*
 * tkUndo.h --
 *
 *	Declarations shared among the files that implement an undo stack.
 *
 * Copyright (c) 2002 Ludwig Callewaert.
 * Copyright © 2002 Ludwig Callewaert.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKUNDO
#define _TKUNDO

Changes to generic/tkUtil.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






-
-
+
+







/*
 * tkUtil.c --
 *
 *	This file contains miscellaneous utility functions that are used by
 *	the rest of Tk, such as a function for drawing a focus highlight.
 *
 * Copyright (c) 1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

660
661
662
663
664
665
666

667
668
669
670
671
672
673
674

675
676

677
678
679
680
681
682
683
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674

675
676
677
678
679
680
681
682
683
684
685







+







-
+


+







	}
	if (Tcl_GetDouble(interp, argv[3], dblPtr) != TCL_OK) {
	    return TK_SCROLL_ERROR;
	}
	return TK_SCROLL_MOVETO;
    } else if ((c == 's')
	    && (strncmp(argv[2], "scroll", length) == 0)) {
	double d;
	if (argc != 5) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "wrong # args: should be \"%s %s %s\"",
		    argv[0], argv[1], "scroll number pages|units"));
	    Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
	    return TK_SCROLL_ERROR;
	}
	if (Tcl_GetInt(interp, argv[3], intPtr) != TCL_OK) {
	if (Tcl_GetDouble(interp, argv[3], &d) != TCL_OK) {
	    return TK_SCROLL_ERROR;
	}
	*intPtr = (d > 0) ? ceil(d) : floor(d);
	length = strlen(argv[4]);
	c = argv[4][0];
	if ((c == 'p') && (strncmp(argv[4], "pages", length) == 0)) {
	    return TK_SCROLL_PAGES;
	} else if ((c == 'u') && (strncmp(argv[4], "units", length) == 0)) {
	    return TK_SCROLL_UNITS;
	}
725
726
727
728
729
730
731
732

733
734
735
736
737
738
739
740
741
742
743
744
745
746

747
748
749
750
751

752
753



754
755



756
757
758
759
760
761
762
727
728
729
730
731
732
733

734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753

754
755
756
757
758
759


760
761
762
763
764
765
766
767
768
769







-
+














+




-
+


+
+
+
-
-
+
+
+







    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_GetStringFromObj(objv[2], &length);

#define ArgPfxEq(str) \
	((arg[0] == str[0]) && !strncmp(arg, str, length))

    if (ArgPfxEq("moveto")) {
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "moveto fraction");
	    return TK_SCROLL_ERROR;
	}
	if (Tcl_GetDoubleFromObj(interp, objv[3], dblPtr) != TCL_OK) {
	    return TK_SCROLL_ERROR;
	}
	return TK_SCROLL_MOVETO;
    } else if (ArgPfxEq("scroll")) {
	double d;
	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "scroll number pages|units");
	    return TK_SCROLL_ERROR;
	}
	if (Tcl_GetIntFromObj(interp, objv[3], intPtr) != TCL_OK) {
	if (Tcl_GetDoubleFromObj(interp, objv[3], &d) != TCL_OK) {
	    return TK_SCROLL_ERROR;
	}
	*intPtr = (d >= 0) ? ceil(d) : floor(d);
	if (dblPtr) {
	    *dblPtr = d;

	arg = TkGetStringFromObj(objv[4], &length);
	}

	arg = Tcl_GetStringFromObj(objv[4], &length);
	if (ArgPfxEq("pages")) {
	    return TK_SCROLL_PAGES;
	} else if (ArgPfxEq("units")) {
	    return TK_SCROLL_UNITS;
	}

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
1126
1127
1128
1129
1130
1131
1132
1133

1134
1135
1136
1137
1138
1139
1140
1133
1134
1135
1136
1137
1138
1139

1140
1141
1142
1143
1144
1145
1146
1147







-
+







    if (!(strlen(namesp) == 2 && namesp[1] == ':')) {
	Tcl_DStringAppend(&ds, "::", -1);
    }
    Tcl_DStringAppend(&ds, name, -1);

    dictObj = Tcl_NewObj();
    for (i = 0; map[i].name != NULL ; ++i) {
	Tcl_Obj *nameObj, *fqdnObj;
	Tcl_Obj *fqdnObj;

	nameObj = Tcl_NewStringObj(map[i].name, -1);
	fqdnObj = Tcl_NewStringObj(Tcl_DStringValue(&ds),
		Tcl_DStringLength(&ds));
	Tcl_AppendStringsToObj(fqdnObj, "::", map[i].name, NULL);
	Tcl_DictObjPut(NULL, dictObj, nameObj, fqdnObj);
	if (map[i].proc) {
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
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







-
+












-
+







    Tcl_DStringFree(&ds);
    return ensemble;
}

/*
 *----------------------------------------------------------------------
 *
 * TkSendVirtualEvent --
 * Tk_SendVirtualEvent --
 *
 * 	Send a virtual event notification to the specified target window.
 * 	Equivalent to:
 * 	    "event generate $target <<$eventName>> -data $detail"
 *
 * 	Note that we use Tk_QueueWindowEvent, not Tk_HandleEvent, so this
 * 	routine does not reenter the interpreter.
 *
 *----------------------------------------------------------------------
 */

void
TkSendVirtualEvent(
Tk_SendVirtualEvent(
    Tk_Window target,
    const char *eventName,
    Tcl_Obj *detail)
{
    union {XEvent general; XVirtualEvent virt;} event;

    memset(&event, 0, sizeof(event));
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
1308
1309
1310
1311
1312
1313
1314













1315
1316
1317
1318
1319
1320
1321







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







    }
#endif

    return (first + TkUtfToUniChar(first, &ch) >= src) ? first : p ;
}

#endif

#if TCL_MAJOR_VERSION > 8
unsigned char *
TkGetByteArrayFromObj(
	Tcl_Obj *objPtr,
	size_t *lengthPtr
) {
    unsigned char *result = Tcl_GetByteArrayFromObj(objPtr, NULL);
    *lengthPtr = *(size_t *) objPtr->internalRep.twoPtrValue.ptr1;
    return result;
}
#endif /* TCL_MAJOR_VERSION > 8 */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkVisual.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







-
-
+
+







/*
 * tkVisual.c --
 *
 *	This file contains library procedures for allocating and freeing
 *	visuals and colormaps. This code is based on a prototype
 *	implementation by Paul Mackerras.
 *
 * Copyright (c) 1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

Changes to generic/tkWindow.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







-
-
+
+






-
+







/*
 * tkWindow.c --
 *
 *	This file provides basic window-manipulation functions, which are
 *	equivalent to functions in Xlib (and even invoke them) but also
 *	maintain the local Tk_Window structure.
 *
 * Copyright (c) 1989-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1989-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#include "tkPort.h"
#ifdef _WIN32
#include "tkWinInt.h"
#elif !defined(MAC_OSX_TK)
#include "tkUnixInt.h"
#endif

/*
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
235
236
237
238
239
240
241


242
243
244
245
246
247
248







-
-








static void
TkCloseDisplay(
    TkDisplay *dispPtr)
{
    TkClipCleanup(dispPtr);

    TkpCancelWarp(dispPtr);

    if (dispPtr->name != NULL) {
	ckfree(dispPtr->name);
    }

    if (dispPtr->atomInit) {
	Tcl_DeleteHashTable(&dispPtr->nameTable);
	Tcl_DeleteHashTable(&dispPtr->atomTable);
918
919
920
921
922
923
924
925

926
927
928
929
930
931
932
916
917
918
919
920
921
922

923
924
925
926
927
928
929
930







-
+







    isSafe = Tcl_IsSafe(interp);
    for (cmdPtr = commands; cmdPtr->name != NULL; cmdPtr++) {
	if (cmdPtr->objProc == NULL) {
	    Tcl_Panic("TkCreateMainWindow: builtin command with NULL string and object procs");
	}

#if defined(_WIN32) && !defined(STATIC_BUILD)
	if ((cmdPtr->flags & WINMACONLY) && tclStubsPtr->reserved9) {
	if ((cmdPtr->flags & WINMACONLY) && tclStubsPtr->tcl_CreateFileHandler) {
	    /*
	     * We are running on Cygwin, so don't use the win32 dialogs.
	     */

	    continue;
	}
#endif /* _WIN32 && !STATIC_BUILD */
1640
1641
1642
1643
1644
1645
1646
1647

1648
1649
1650
1651
1652
1653
1654
1638
1639
1640
1641
1642
1643
1644

1645
1646
1647
1648
1649
1650
1651
1652







-
+







    event.type = MapNotify;
    event.xmap.serial = LastKnownRequestProcessed(winPtr->display);
    event.xmap.send_event = False;
    event.xmap.display = winPtr->display;
    event.xmap.event = winPtr->window;
    event.xmap.window = winPtr->window;
    event.xmap.override_redirect = winPtr->atts.override_redirect;
    Tk_HandleEvent(&event);
    TkpHandleMapOrUnmap((Tk_Window)winPtr, &event);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_MakeWindowExist --
 *
1802
1803
1804
1805
1806
1807
1808
1809

1810
1811
1812
1813
1814
1815
1816
1800
1801
1802
1803
1804
1805
1806

1807
1808
1809
1810
1811
1812
1813
1814







-
+







	event.type = UnmapNotify;
	event.xunmap.serial = LastKnownRequestProcessed(winPtr->display);
	event.xunmap.send_event = False;
	event.xunmap.display = winPtr->display;
	event.xunmap.event = winPtr->window;
	event.xunmap.window = winPtr->window;
	event.xunmap.from_configure = False;
	Tk_HandleEvent(&event);
	TkpHandleMapOrUnmap((Tk_Window)winPtr, &event);
    }
}

void
Tk_ConfigureWindow(
    Tk_Window tkwin,		/* Window to re-configure. */
    unsigned int valueMask,	/* Mask indicating which parts of *valuePtr
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
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







-
+

















-
+








    return tsdPtr->numMainWindows;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpAlwaysShowSelection --
 * Tk_AlwaysShowSelection --
 *
 *	Indicates whether text/entry widgets should always display
 *	their selection, regardless of window focus.
 *
 * Results:
 *	The return value is 1 if always showing the selection has been
 *	requested for tkwin's application by setting the
 *	::tk::AlwaysShowSelection variable in its interpreter to a true value.
 *	0 is returned if it has a false value.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkpAlwaysShowSelection(
Tk_AlwaysShowSelection(
    Tk_Window tkwin)		/* Window whose application is to be
				 * checked. */
{
    return ((TkWindow *) tkwin)->mainPtr->alwaysShowSelection;
}

/*
2957
2958
2959
2960
2961
2962
2963
2964

2965
2966
2967
2968
2969
2970
2971
2955
2956
2957
2958
2959
2960
2961

2962
2963
2964
2965
2966
2967
2968
2969







-
+







     * - Wm is unsafe because (if toplevels are allowed, in the future) it can
     *   be used to remove decorations, move windows around, cover the entire
     *   screen etc etc.
     *
     * Current risks:
     *
     * - No CPU time limit, no memory allocation limits, no color limits.
     *   CPU time limits can be imposed by an unsafe master interpreter.
     *   CPU time limits can be imposed by an unsafe parent interpreter.
     *
     * The actual code called is the same as Tk_Init but Tcl_IsSafe() is
     * checked at several places to differentiate the two initialisations.
     */

#if defined(_WIN32)
    if (tkcygwindll) {
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
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







-
+



-
+





-
+

-
-
-
+
+
+

-
-
+
+








-
+





-
+





-
+


-
-
+
+



-
+

-
+





-
+







     */

    Tcl_ResetResult(interp);

    if (Tcl_IsSafe(interp)) {
	/*
	 * Get the clearance to start Tk and the "argv" parameters from the
	 * master.
	 * parent.
	 */

	/*
	 * Step 1 : find the master and construct the interp name (could be a
	 * Step 1 : find the parent and construct the interp name (could be a
	 * function if new APIs were ok). We could also construct the path
	 * while walking, but there is no API to get the name of an interp
	 * either.
	 */

	Tcl_Interp *master = interp;
	Tcl_Interp *parent = interp;

	while (Tcl_IsSafe(master)) {
	    master = Tcl_GetMaster(master);
	    if (master == NULL) {
	while (Tcl_IsSafe(parent)) {
	    parent = Tcl_GetParent(parent);
	    if (parent == NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"no controlling master interpreter", -1));
		Tcl_SetErrorCode(interp, "TK", "SAFE", "NO_MASTER", NULL);
			"no controlling parent interpreter", -1));
		Tcl_SetErrorCode(interp, "TK", "SAFE", "NO_PARENT", NULL);
		return TCL_ERROR;
	    }
	}

	/*
	 * Construct the name (rewalk...)
	 */

	code = Tcl_GetInterpPath(master, interp);
	code = Tcl_GetInterpPath(parent, interp);
	if (code != TCL_OK) {
	    Tcl_Panic("Tcl_GetInterpPath broken!");
	}

	/*
	 * Build the command to eval in trusted master.
	 * Build the command to eval in trusted parent.
	 */

	cmd = Tcl_NewListObj(2, NULL);
	Tcl_ListObjAppendElement(NULL, cmd,
		Tcl_NewStringObj("::safe::TkInit", -1));
	Tcl_ListObjAppendElement(NULL, cmd, Tcl_GetObjResult(master));
	Tcl_ListObjAppendElement(NULL, cmd, Tcl_GetObjResult(parent));

	/*
	 * Step 2 : Eval in the master. The argument is the *reversed* interp
	 * path of the slave.
	 * Step 2 : Eval in the parent. The argument is the *reversed* interp
	 * path of the child.
	 */

	Tcl_IncrRefCount(cmd);
	code = Tcl_EvalObjEx(master, cmd, 0);
	code = Tcl_EvalObjEx(parent, cmd, 0);
	Tcl_DecrRefCount(cmd);
	Tcl_TransferResult(master, code, interp);
	Tcl_TransferResult(parent, code, interp);
	if (code != TCL_OK) {
	    return code;
	}

	/*
	 * Use the master's result as argv. Note: We don't use the Obj
	 * Use the parent's result as argv. Note: We don't use the Obj
	 * interfaces to avoid dealing with cross interp refcounting and
	 * changing the code below.
	 */

	value = Tcl_GetObjResult(interp);
    } else {
	/*
3199
3200
3201
3202
3203
3204
3205
3206

3207
3208
3209
3210
3211
3212
3213
3197
3198
3199
3200
3201
3202
3203

3204
3205
3206
3207
3208
3209
3210
3211







-
+








    /*
     * The -class argument is always the ToTitle of the -name
     */

    {
	TkSizeT numBytes;
	const char *bytes = TkGetStringFromObj(nameObj, &numBytes);
	const char *bytes = Tcl_GetStringFromObj(nameObj, &numBytes);

	classObj = Tcl_NewStringObj(bytes, numBytes);

	numBytes = Tcl_UtfToTitle(Tcl_GetString(classObj));
	Tcl_SetObjLength(classObj, numBytes);
    }

3281
3282
3283
3284
3285
3286
3287
3288

3289
3290

3291




3292
3293
3294
3295
3296
3297
3298
3279
3280
3281
3282
3283
3284
3285

3286
3287
3288
3289

3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300







-
+


+
-
+
+
+
+







	geometryObj = NULL;
	if (code != TCL_OK) {
	    goto done;
	}
    }

    /*
     * Provide Tk and its stub table.
     * Provide "tk" and its stub table.
     */

#ifndef TK_NO_DEPRECATED
    code = Tcl_PkgProvideEx(interp, "Tk", TK_PATCH_LEVEL,
    Tcl_PkgProvideEx(interp, "Tk", TK_PATCH_LEVEL,
	    (ClientData) &tkStubs);
#endif
    code = Tcl_PkgProvideEx(interp, "tk", TK_PATCH_LEVEL,
	    (ClientData) &tkStubs);
    if (code != TCL_OK) {
	goto done;
    }

    /*
     * If we were able to provide ourselves as a package, then set the main
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
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







-
+











-
+



-
+













const char *
Tk_PkgInitStubsCheck(
    Tcl_Interp *interp,
    const char * version,
    int exact)
{
    const char *actualVersion = Tcl_PkgRequireEx(interp, "Tk", version, 0, NULL);
    const char *actualVersion = Tcl_PkgRequireEx(interp, "tk", version, 0, NULL);

    if (exact && actualVersion) {
	const char *p = version;
	int count = 0;

	while (*p) {
	    count += !isdigit(UCHAR(*p++));
	}
	if (count == 1) {
	    if (0 != strncmp(version, actualVersion, strlen(version))) {
		/* Construct error message */
		Tcl_PkgPresentEx(interp, "Tk", version, 1, NULL);
		Tcl_PkgPresentEx(interp, "tk", version, 1, NULL);
		return NULL;
	    }
	} else {
	    return Tcl_PkgPresentEx(interp, "Tk", version, 1, NULL);
	    return Tcl_PkgPresentEx(interp, "tk", version, 1, NULL);
	}
    }
    return actualVersion;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/ttk/ttkBlink.c.

55
56
57
58
59
60
61
62

63
64
65
66
67
68
69
55
56
57
58
59
60
61

62
63
64
65
66
67
68
69







-
+








    if (!cm) {
	cm = (CursorManager *)ckalloc(sizeof(*cm));
	cm->timer = 0;
	cm->owner = 0;
	cm->onTime = DEF_CURSOR_ON_TIME;
	cm->offTime = DEF_CURSOR_OFF_TIME;
	Tcl_SetAssocData(interp,cm_key,CursorManagerDeleteProc,(ClientData)cm);
	Tcl_SetAssocData(interp, cm_key, CursorManagerDeleteProc, cm);
    }
    return cm;
}

/* CursorBlinkProc --
 *	Timer handler to blink the insert cursor on and off.
 */

Changes to generic/ttk/ttkButton.c.

1
2

3
4
5
6
7
8
9
1

2
3
4
5
6
7
8
9

-
+







/*
 * Copyright (c) 2003, Joe English
 * Copyright © 2003, Joe English
 *
 * label, button, checkbutton, radiobutton, and menubutton widgets.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
81
82
83
84
85
86
87
88

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

88
89
90
91
92
93
94
95







-
+







	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,
	 TK_OPTION_NULL_OK, (void *)ttkCompoundStrings,
         GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-padding", "padding", "Pad",
	NULL, offsetof(Base,base.paddingObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED},

    /*
     * Compatibility/legacy options
269
270
271
272
273
274
275

276
277

278
279
280

281
282
283
284
285
286
287
269
270
271
272
273
274
275
276
277

278
279
280

281
282
283
284
285
286
287
288







+

-
+


-
+







	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED /*SB: SIZE_CHANGED*/ },

    WIDGET_TAKEFOCUS_FALSE,
    WIDGET_INHERIT_OPTIONS(BaseOptionSpecs)
};

static const Ttk_Ensemble LabelCommands[] = {
    { "cget",		TtkWidgetCgetCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec LabelWidgetSpec =
{
    "TLabel",			/* className */
    sizeof(Label),		/* recordSize */
374
375
376
377
378
379
380

381
382

383
384

385
386

387
388
389
390
391
392
393
375
376
377
378
379
380
381
382
383

384

385
386
387

388
389
390
391
392
393
394
395







+

-
+
-

+

-
+







    if (buttonPtr->core.state & TTK_STATE_DISABLED) {
	return TCL_OK;
    }
    return Tcl_EvalObjEx(interp, buttonPtr->button.commandObj, TCL_EVAL_GLOBAL);
}

static const Ttk_Ensemble ButtonCommands[] = {
    { "cget",		TtkWidgetCgetCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "invoke",		ButtonInvokeCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "invoke",		ButtonInvokeCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec ButtonWidgetSpec =
{
    "TButton",			/* className */
    sizeof(Button),		/* recordSize */
581
582
583
584
585
586
587

588
589

590
591

592
593

594
595
596
597
598
599
600
583
584
585
586
587
588
589
590
591

592

593
594
595

596
597
598
599
600
601
602
603







+

-
+
-

+

-
+







	return TCL_ERROR;

    return Tcl_EvalObjEx(interp,
	checkPtr->checkbutton.commandObj, TCL_EVAL_GLOBAL);
}

static const Ttk_Ensemble CheckbuttonCommands[] = {
    { "cget",		TtkWidgetCgetCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "invoke",		CheckbuttonInvokeCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "invoke",		CheckbuttonInvokeCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    /* MISSING: select, deselect, toggle */
    { 0,0,0 }
};

static const WidgetSpec CheckbuttonWidgetSpec =
{
    "TCheckbutton",		/* className */
757
758
759
760
761
762
763

764
765

766
767

768
769

770
771
772
773
774
775
776
760
761
762
763
764
765
766
767
768

769

770
771
772

773
774
775
776
777
778
779
780







+

-
+
-

+

-
+







	return TCL_ERROR;

    return Tcl_EvalObjEx(interp,
	radioPtr->radiobutton.commandObj, TCL_EVAL_GLOBAL);
}

static const Ttk_Ensemble RadiobuttonCommands[] = {
    { "cget",		TtkWidgetCgetCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "invoke",		RadiobuttonInvokeCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "invoke",		RadiobuttonInvokeCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    /* MISSING: select, deselect */
    { 0,0,0 }
};

static const WidgetSpec RadiobuttonWidgetSpec =
{
    "TRadiobutton",		/* className */
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
823
824
825
826
827
828
829

830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849







-
+











+







};
static const Tk_OptionSpec MenubuttonOptionSpecs[] =
{
    {TK_OPTION_STRING, "-menu", "menu", "Menu",
	"", offsetof(Menubutton, menubutton.menuObj), TCL_INDEX_NONE, 0,0,0},
    {TK_OPTION_STRING_TABLE, "-direction", "direction", "Direction",
	"below", offsetof(Menubutton, menubutton.directionObj), TCL_INDEX_NONE,
	0,(ClientData)directionStrings,GEOMETRY_CHANGED},
	0, (void *)directionStrings, GEOMETRY_CHANGED},

    WIDGET_TAKEFOCUS_TRUE,
    WIDGET_INHERIT_OPTIONS(BaseOptionSpecs)
};

static const Ttk_Ensemble MenubuttonCommands[] = {
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec MenubuttonWidgetSpec =
{
    "TMenubutton",		/* className */
    sizeof(Menubutton), 	/* recordSize */
854
855
856
857
858
859
860
861

862
863
864
865
866
867
868
859
860
861
862
863
864
865

866
867
868
869
870
871
872
873







-
+







    TtkWidgetDisplay		/* displayProc */
};

TTK_BEGIN_LAYOUT(MenubuttonLayout)
    TTK_GROUP("Menubutton.border", TTK_FILL_BOTH,
	TTK_GROUP("Menubutton.focus", TTK_FILL_BOTH,
	    TTK_NODE("Menubutton.indicator", TTK_PACK_RIGHT)
	    TTK_GROUP("Menubutton.padding", TTK_PACK_LEFT|TTK_EXPAND|TTK_FILL_X,
	    TTK_GROUP("Menubutton.padding", TTK_FILL_X,
	        TTK_NODE("Menubutton.label", TTK_PACK_LEFT))))
TTK_END_LAYOUT

/*------------------------------------------------------------------------
 * +++ Initialization.
 */

Changes to generic/ttk/ttkCache.c.

1
2
3
4

5
6
7
8
9
10
11
1
2
3

4
5
6
7
8
9
10
11



-
+







/*
 *      Theme engine resource cache.
 *
 * Copyright (c) 2004, Joe English
 * Copyright © 2004, Joe English
 *
 * The problem:
 *
 * Tk maintains reference counts for fonts, colors, and images,
 * and deallocates them when the reference count goes to zero.
 * With the theme engine, resources are allocated right before
 * drawing an element and released immediately after.

Changes to generic/ttk/ttkClamTheme.c.

1
2

3
4
5
6
7
8
9
1

2
3
4
5
6
7
8
9

-
+







/*
 * Copyright (C) 2004 Joe English
 * Copyright © 2004 Joe English
 *
 * "clam" theme; inspired by the XFCE family of Gnome themes.
 */

#include "tkInt.h"
#include "ttkTheme.h"

951
952
953
954
955
956
957
958

959
960
961
962
963
964
965
951
952
953
954
955
956
957

958
959
960
961
962
963
964
965







-
+







 * +++ Modified widget layouts.
 */

TTK_BEGIN_LAYOUT_TABLE(LayoutTable)

TTK_LAYOUT("TCombobox",
    TTK_NODE("Combobox.downarrow", TTK_PACK_RIGHT|TTK_FILL_Y)
    TTK_GROUP("Combobox.field", TTK_PACK_LEFT|TTK_FILL_BOTH|TTK_EXPAND,
    TTK_GROUP("Combobox.field", TTK_FILL_BOTH,
	TTK_GROUP("Combobox.padding", TTK_FILL_BOTH,
	    TTK_NODE("Combobox.textarea", TTK_FILL_BOTH))))

TTK_LAYOUT("Horizontal.Sash",
    TTK_GROUP("Sash.hsash", TTK_FILL_BOTH,
	TTK_NODE("Sash.hgrip", TTK_FILL_BOTH)))

Changes to generic/ttk/ttkClassicTheme.c.

1
2

3
4
5
6
7
8
9
1

2
3
4
5
6
7
8
9

-
+







/*
 * Copyright (c) 2004, Joe English
 * Copyright © 2004, Joe English
 *
 * "classic" theme; implements the classic Motif-like Tk look.
 *
 */

#include "tkInt.h"
#include "ttkTheme.h"
449
450
451
452
453
454
455
456

457
458
459
460
461
462
463
449
450
451
452
453
454
455

456
457
458
459
460
461
462
463







-
+







	        TTK_NODE("Radiobutton.indicator", TTK_PACK_LEFT)
	        TTK_NODE("Radiobutton.label", TTK_PACK_LEFT|TTK_FILL_BOTH)))))

TTK_LAYOUT("TMenubutton",
    TTK_GROUP("Menubutton.highlight", TTK_FILL_BOTH,
        TTK_GROUP("Menubutton.border", TTK_FILL_BOTH,
	    TTK_NODE("Menubutton.indicator", TTK_PACK_RIGHT)
	    TTK_GROUP("Menubutton.padding", TTK_PACK_LEFT|TTK_EXPAND|TTK_FILL_X,
	    TTK_GROUP("Menubutton.padding", TTK_FILL_X,
	        TTK_NODE("Menubutton.label", 0)))))

/* "classic" entry, includes highlight border */
TTK_LAYOUT("TEntry",
    TTK_GROUP("Entry.highlight", TTK_FILL_BOTH,
        TTK_GROUP("Entry.field", TTK_FILL_BOTH|TTK_BORDER,
	    TTK_GROUP("Entry.padding", TTK_FILL_BOTH,

Changes to generic/ttk/ttkDecls.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
24
25
26
27







+
-
+
+
+
+








extern const char *TtkInitializeStubs(
	Tcl_Interp *, const char *version, int epoch, int revision);
#define Ttk_InitStubs(interp) TtkInitializeStubs( \
	interp, TTK_VERSION, TTK_STUBS_EPOCH, TTK_STUBS_REVISION)
#else

#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
#define Ttk_InitStubs(interp) Tcl_PkgRequireEx(interp, "Ttk", TTK_VERSION, 0, NULL)
#   define Ttk_InitStubs(interp) Tcl_PkgRequireEx(interp, "Ttk", TTK_VERSION, 0, NULL)
#else
#   define Ttk_InitStubs(interp) Tcl_PkgRequireEx(interp, "ttk", TTK_VERSION, 0, NULL)
#endif

#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

Changes to generic/ttk/ttkDefaultTheme.c.

1
2

3
4
5
6
7
8
9
1

2
3
4
5
6
7
8
9

-
+







/*
 * Copyright (c) 2003, Joe English
 * Copyright © 2003 Joe English
 *
 * Tk alternate theme, intended to match the MSUE and Gtk's (old) default theme
 */

#include "tkInt.h"
#include "ttkTheme.h"

Changes to generic/ttk/ttkElements.c.

1
2

3
4
5
6
7
8
9
1

2
3
4
5
6
7
8
9

-
+







/*
 * Copyright (c) 2003, Joe English
 * Copyright © 2003 Joe English
 *
 * Default implementation for themed elements.
 *
 */

#include "tkInt.h"
#include "ttkTheme.h"

Changes to generic/ttk/ttkEntry.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



-
-
-
-
-
+
+
+
+
+







/*
 * DERIVED FROM: tk/generic/tkEntry.c r1.35.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 2000 Ajuba Solutions.
 * Copyright (c) 2002 ActiveState Corporation.
 * Copyright (c) 2004 Joe English
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 2000 Ajuba Solutions.
 * Copyright © 2002 ActiveState Corporation.
 * Copyright © 2004 Joe English
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

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







-
+







	"normal", offsetof(Entry, entry.stateObj), TCL_INDEX_NONE,
        0,0,STATE_CHANGED},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	NULL, offsetof(Entry, entry.textVariableObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,TEXTVAR_CHANGED},
    {TK_OPTION_STRING_TABLE, "-validate", "validate", "Validate",
	"none", TCL_INDEX_NONE, offsetof(Entry, entry.validate),
	0, (ClientData) validateStrings, 0},
	0, (void *) validateStrings, 0},
    {TK_OPTION_STRING, "-validatecommand", "validateCommand", "ValidateCommand",
	NULL, TCL_INDEX_NONE, offsetof(Entry, entry.validateCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-width", "width", "Width",
	DEF_ENTRY_WIDTH, offsetof(Entry, entry.widthObj), TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED},
    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
321
322
323
324
325
326
327
328

329
330
331
332
333
334
335
321
322
323
324
325
326
327

328
329
330
331
332
333
334
335







-
+







    if ((entryPtr->entry.numChars != 0) || (entryPtr->entry.placeholderObj == NULL)) {
        entryPtr->entry.textLayout = Tk_ComputeTextLayout(
	    Tk_GetFontFromObj(entryPtr->core.tkwin, entryPtr->entry.fontObj),
	    entryPtr->entry.displayString, entryPtr->entry.numChars,
	    0/*wraplength*/, entryPtr->entry.justify, TK_IGNORE_NEWLINES,
	    &entryPtr->entry.layoutWidth, &entryPtr->entry.layoutHeight);
    } else {
        text = TkGetStringFromObj(entryPtr->entry.placeholderObj, &length);
        text = Tcl_GetStringFromObj(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);
    }
}
399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413







-
+







 */
static void EntryOwnSelection(Entry *entryPtr)
{
    if (entryPtr->entry.exportSelection
	&& (!Tcl_IsSafe(entryPtr->core.interp))
	&& !(entryPtr->core.flags & GOT_SELECTION)) {
	Tk_OwnSelection(entryPtr->core.tkwin, XA_PRIMARY, EntryLostSelection,
		(ClientData) entryPtr);
		entryPtr);
	entryPtr->core.flags |= GOT_SELECTION;
    }
}

/*------------------------------------------------------------------------
 * +++ Validation.
 */
596
597
598
599
600
601
602
603

604
605

606
607
608
609
610
611
612
596
597
598
599
600
601
602

603
604

605
606
607
608
609
610
611
612







-
+

-
+







    TkSizeT count,			/* #changed characters */
    VREASON reason)		/* Reason for change */
{
    Tcl_Interp *interp = entryPtr->core.interp;
    VMODE vmode = entryPtr->entry.validate;
    int code, change_ok;

    if (   (entryPtr->entry.validateCmd == NULL)
    if ((entryPtr->entry.validateCmd == NULL)
	|| (entryPtr->core.flags & VALIDATING)
	|| !EntryNeedsValidation(vmode, reason) )
	|| !EntryNeedsValidation(vmode, reason))
    {
	return TCL_OK;
    }

    entryPtr->core.flags |= VALIDATING;

    /* Run -validatecommand and check return value:
954
955
956
957
958
959
960
961

962
963
964
965
966
967
968
954
955
956
957
958
959
960

961
962
963
964
965
966
967
968







-
+







{
    Entry *entryPtr = (Entry *)recordPtr;
    (void)dummy;

    Tk_CreateEventHandler(
	entryPtr->core.tkwin, EntryEventMask, EntryEventProc, entryPtr);
    Tk_CreateSelHandler(entryPtr->core.tkwin, XA_PRIMARY, XA_STRING,
	EntryFetchSelection, (ClientData) entryPtr, 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;
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
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







-
+




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

-
-
+
+
-





+
+
+
+
+
+
+
+
+
+







	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);
	(void)Tcl_GetStringFromObj(entryPtr->entry.placeholderObj, &rightIndex);
    } else {
	foregroundObj = es.foregroundObj;
    }
    gc = EntryGetGC(entryPtr, foregroundObj, clipRegion);
    if (showSelection) {

        /* Draw the selected and unselected portions separately.
	 */
	if (leftIndex < selFirst) {
    Tk_DrawTextLayout(
	Tk_Display(tkwin), d, gc, entryPtr->entry.textLayout,
	entryPtr->entry.layoutX, entryPtr->entry.layoutY,
	leftIndex, rightIndex);
    XSetClipMask(Tk_Display(tkwin), gc, None);
    Tk_FreeGC(Tk_Display(tkwin), gc);
	    Tk_DrawTextLayout(
		Tk_Display(tkwin), d, gc, entryPtr->entry.textLayout,
		entryPtr->entry.layoutX, entryPtr->entry.layoutY,
		leftIndex, selFirst);
	}
	if (selLast < rightIndex) {
	    Tk_DrawTextLayout(
		Tk_Display(tkwin), d, gc, entryPtr->entry.textLayout,
		entryPtr->entry.layoutX, entryPtr->entry.layoutY,
		selLast, rightIndex);
	}
	XSetClipMask(Tk_Display(tkwin), gc, None);
	Tk_FreeGC(Tk_Display(tkwin), gc);

    /* Overwrite the selected portion (if any) in the -selectforeground color:
     */
	/* Draw the selected portion in the -selectforeground color:
	 */
    if (showSelection) {
	gc = EntryGetGC(entryPtr, es.selForegroundObj, clipRegion);
	Tk_DrawTextLayout(
	    Tk_Display(tkwin), d, gc, entryPtr->entry.textLayout,
	    entryPtr->entry.layoutX, entryPtr->entry.layoutY,
	    selFirst, selLast);
	XSetClipMask(Tk_Display(tkwin), gc, None);
	Tk_FreeGC(Tk_Display(tkwin), gc);
    } else {

        /* Draw the entire visible text
         */
	Tk_DrawTextLayout(
	    Tk_Display(tkwin), d, gc, entryPtr->entry.textLayout,
	    entryPtr->entry.layoutX, entryPtr->entry.layoutY,
	    leftIndex, rightIndex);
	XSetClipMask(Tk_Display(tkwin), gc, None);
	Tk_FreeGC(Tk_Display(tkwin), gc);
    }

    /* Drop the region. Note that we have to manually remove the reference to
     * it from the Xft guts (if they're being used).
     */
1368
1369
1370
1371
1372
1373
1374
1375

1376
1377
1378
1379
1380
1381
1382

1383
1384
1385
1386
1387
1388
1389
1389
1390
1391
1392
1393
1394
1395

1396
1397
1398
1399
1400
1401
1402

1403
1404
1405
1406
1407
1408
1409
1410







-
+






-
+







    TkSizeT *indexPtr)		/* Return value */
{
#   define EntryWidth(e) (Tk_Width(entryPtr->core.tkwin)) /* Not Right */
    TkSizeT length, idx;
    const char *string;

    if (TCL_OK == TkGetIntForIndex(indexObj, entryPtr->entry.numChars - 1, 1, &idx)) {
    	if (idx + 1 > entryPtr->entry.numChars + 1) {
    	if ((idx != TCL_INDEX_NONE) && (idx > entryPtr->entry.numChars)) {
    	    idx = entryPtr->entry.numChars;
    	}
    	*indexPtr = idx;
    	return TCL_OK;
    }

    string = TkGetStringFromObj(indexObj, &length);
    string = Tcl_GetStringFromObj(indexObj, &length);

    if (strncmp(string, "insert", length) == 0) {
	*indexPtr = entryPtr->entry.insertPos;
    } else if (strncmp(string, "left", length) == 0) {	/* for debugging */
	*indexPtr = entryPtr->entry.xscroll.first;
    } else if (strncmp(string, "right", length) == 0) {	/* for debugging */
	*indexPtr = entryPtr->entry.xscroll.last;
1552
1553
1554
1555
1556
1557
1558
1559

1560
1561
1562
1563
1564
1565
1566
1573
1574
1575
1576
1577
1578
1579

1580
1581
1582
1583
1584
1585
1586
1587







-
+







    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "string");
	return TCL_ERROR;
    }
    if (EntryIndex(interp, entryPtr, objv[2], &index) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index));
    Tcl_SetObjResult(interp, TkNewIndexObj(index));
    return TCL_OK;
}

/* $entry insert $index $text --
 * 	Insert $text after position $index.
 * 	Silent no-op if the entry is disabled or read-only.
 */
1625
1626
1627
1628
1629
1630
1631
1632

1633
1634
1635
1636
1637
1638
1639
1646
1647
1648
1649
1650
1651
1652

1653
1654
1655
1656
1657
1658
1659
1660







-
+







{
    Entry *entryPtr = (Entry *)recordPtr;
    TkSizeT start, end;
    if (objc != 5) {
	Tcl_WrongNumArgs(interp, 3, objv, "start end");
	return TCL_ERROR;
    }
    if (    EntryIndex(interp, entryPtr, objv[3], &start) != TCL_OK
    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;
    }

1686
1687
1688
1689
1690
1691
1692
1693

1694
1695
1696
1697
1698
1699
1700
1707
1708
1709
1710
1711
1712
1713

1714
1715
1716
1717
1718
1719
1720
1721







-
+







    }

    code = EntryRevalidate(interp, entryPtr, VALIDATE_FORCED);

    if (code == TCL_ERROR)
	return code;

    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(code == TCL_OK));
    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(code == TCL_OK));
    return TCL_OK;
}

/* $entry xview	-- horizontal scrolling interface
 */
static int EntryXViewCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
1720
1721
1722
1723
1724
1725
1726

1727
1728
1729
1730
1731
1732
1733
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755







+







    { "icursor", 	EntryICursorCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "index", 		EntryIndexCommand,0 },
    { "insert", 	EntryInsertCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "selection", 	0,EntrySelectionCommands },
    { "state",  	TtkWidgetStateCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    { "validate", 	EntryValidateCommand,0 },
    { "xview", 		EntryXViewCommand,0 },
    { 0,0,0 }
};

/*------------------------------------------------------------------------
 * +++ Entry widget definition.
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
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







-
+

















-
+







    Tcl_Obj **values;

    Tcl_ListObjGetElements(interp, cbPtr->combobox.valuesObj, &nValues, &values);

    if (objc == 2) {
	/* Check if currentIndex still valid:
	 */
	if (    currentIndex == TCL_INDEX_NONE
	if (currentIndex == TCL_INDEX_NONE
	     || currentIndex >= (TkSizeT)nValues
	     || strcmp(currentValue,Tcl_GetString(values[currentIndex]))
	   )
	{
	    /* Not valid.  Check current value against each element in -values:
	     */
	    for (currentIndex = 0; currentIndex < (TkSizeT)nValues; ++currentIndex) {
		if (!strcmp(currentValue,Tcl_GetString(values[currentIndex]))) {
		    break;
		}
	    }
	    if (currentIndex >= (TkSizeT)nValues) {
		/* Not found */
		currentIndex = TCL_INDEX_NONE;
	    }
	}
	cbPtr->combobox.currentIndex = currentIndex;
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj((int)currentIndex));
	Tcl_SetObjResult(interp, TkNewIndexObj(currentIndex));
	return TCL_OK;
    } else if (objc == 3) {
	TkSizeT idx;

	if (TCL_OK == TkGetIntForIndex(objv[2], nValues - 1, 0, &idx)) {
	    if (idx == TCL_INDEX_NONE || idx > (TkSizeT)nValues) {
	        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
1888
1889
1890
1891
1892
1893
1894

1895
1896

1897
1898
1899
1900
1901
1902
1903
1910
1911
1912
1913
1914
1915
1916
1917
1918

1919
1920
1921
1922
1923
1924
1925
1926







+

-
+







    { "get", 		EntryGetCommand,0 },
    { "icursor", 	EntryICursorCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "index", 		EntryIndexCommand,0 },
    { "insert", 	EntryInsertCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "selection", 	0,EntrySelectionCommands },
    { "set", 		EntrySetCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "set", 		EntrySetCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    { "validate",	EntryValidateCommand,0 },
    { "xview", 		EntryXViewCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec ComboboxWidgetSpec = {
    "TCombobox",		/* className */
2000
2001
2002
2003
2004
2005
2006

2007
2008

2009
2010
2011
2012
2013
2014
2015
2023
2024
2025
2026
2027
2028
2029
2030
2031

2032
2033
2034
2035
2036
2037
2038
2039







+

-
+







    { "get", 		EntryGetCommand,0 },
    { "icursor", 	EntryICursorCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "index", 		EntryIndexCommand,0 },
    { "insert", 	EntryInsertCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "selection", 	0,EntrySelectionCommands },
    { "set", 		EntrySetCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "set", 		EntrySetCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    { "validate",	EntryValidateCommand,0 },
    { "xview", 		EntryXViewCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec SpinboxWidgetSpec = {
    "TSpinbox",			/* className */
2084
2085
2086
2087
2088
2089
2090
2091

2092
2093
2094
2095
2096
2097
2098
2108
2109
2110
2111
2112
2113
2114

2115
2116
2117
2118
2119
2120
2121
2122







-
+







	TTK_GROUP("Entry.padding", TTK_FILL_BOTH,
	    TTK_NODE("Entry.textarea", TTK_FILL_BOTH)))
TTK_END_LAYOUT

TTK_BEGIN_LAYOUT(ComboboxLayout)
    TTK_GROUP("Combobox.field", TTK_FILL_BOTH,
	TTK_NODE("Combobox.downarrow", TTK_PACK_RIGHT|TTK_FILL_Y)
	TTK_GROUP("Combobox.padding", TTK_FILL_BOTH|TTK_PACK_LEFT|TTK_EXPAND,
	TTK_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)

Changes to generic/ttk/ttkFrame.c.

1
2

3
4
5
6
7
8
9
1

2
3
4
5
6
7
8
9

-
+







/*
 * Copyright (c) 2004, Joe English
 * Copyright © 2004 Joe English
 *
 * ttk::frame and ttk::labelframe widgets.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
44
45
46
47
48
49
50

51
52

53
54
55

56
57
58
59
60
61
62
44
45
46
47
48
49
50
51
52

53
54
55

56
57
58
59
60
61
62
63







+

-
+


-
+







	0,0,GEOMETRY_CHANGED },

    WIDGET_TAKEFOCUS_FALSE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

static const Ttk_Ensemble FrameCommands[] = {
    { "cget",   	TtkWidgetCgetCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",   	TtkWidgetCgetCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    { 0,0,0 }
};

/*
 * FrameMargins --
 * 	Compute internal margins for a frame widget.
 * 	This includes the -borderWidth, plus any additional -padding.
84
85
86
87
88
89
90
91




92
93
94
95
96
97
98
99
100
101
102
103
85
86
87
88
89
90
91

92
93
94
95
96
97



98
99
100
101
102
103
104







-
+
+
+
+


-
-
-







    return margins;
}

/* FrameSize procedure --
 * 	The frame doesn't request a size of its own by default,
 * 	but it does have an internal border.  See also <<NOTE-SIZE>>
 */
static int FrameSize(void *recordPtr, int *widthPtr, int *heightPtr)
static int FrameSize(
    void *recordPtr,
    TCL_UNUSED(int *),
    TCL_UNUSED(int *))
{
    Frame *framePtr = (Frame *)recordPtr;
    (void)widthPtr;
    (void)heightPtr;

    Ttk_SetMargins(framePtr->core.tkwin, FrameMargins(framePtr));
    return 0;
}

/*
 * FrameConfigure -- configure hook.
 *	<<NOTE-SIZE>> Usually the size of a frame is controlled by
336
337
338
339
340
341
342
343




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

344
345
346
347
348
349
350
351
352
353


354
355
356
357
358
359
360







-
+
+
+
+






-
-







}

/*
 * LabelframeSize --
 * 	Like the frame, this doesn't request a size of its own
 * 	but it does have internal padding and a minimum size.
 */
static int LabelframeSize(void *recordPtr, int *widthPtr, int *heightPtr)
static int LabelframeSize(
    void *recordPtr,
    TCL_UNUSED(int *),
    TCL_UNUSED(int *))
{
    Labelframe *lframePtr = (Labelframe *)recordPtr;
    WidgetCore *corePtr = &lframePtr->core;
    Ttk_Padding margins;
    LabelframeStyle style;
    int labelWidth, labelHeight;
    (void)widthPtr;
    (void)heightPtr;

    LabelframeStyleOptions(lframePtr, &style);

    /* Compute base margins (See also: FrameMargins)
     */
    margins = Ttk_AddPadding(
		style.padding, Ttk_UniformPadding((short)style.borderWidth));
456
457
458
459
460
461
462
463

464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479

480
481
482

483
484
485
486

487
488
489
490
491


492
493
494
495

496
497
498
499




500
501

502
503
504
505
506
507
508
509
510

511
512



513
514
515
516
517
518
519
520
521

522
523

524
525
526
527
528
529
530
531



532
533
534
535
536
537
538
539
540
541
458
459
460
461
462
463
464

465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480

481
482
483

484
485
486
487

488
489
490
491


492
493
494
495
496

497




498
499
500
501


502
503
504
505
506
507
508
509
510

511
512

513
514
515
516
517

518
519
520
521
522

523
524

525
526
527
528
529
530
531
532

533
534
535
536
537

538
539
540
541
542
543
544







-
+















-
+


-
+



-
+



-
-
+
+



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








-
+

-
+
+
+


-





-
+

-
+







-
+
+
+


-







     * Place border and label:
     */
    Ttk_PlaceLayout(corePtr->layout, corePtr->state, borderParcel);
    if (lframePtr->label.labelLayout) {
	Ttk_PlaceLayout(
	    lframePtr->label.labelLayout, corePtr->state, labelParcel);
    }
    /* labelWidget placed in LabelframePlaceSlaves GM hook */
    /* labelWidget placed in LabelframePlaceContent GM hook */
    lframePtr->label.labelParcel = labelParcel;
}

static void LabelframeDisplay(void *recordPtr, Drawable d)
{
    Labelframe *lframePtr = (Labelframe *)recordPtr;
    Ttk_DrawLayout(lframePtr->core.layout, lframePtr->core.state, d);
    if (lframePtr->label.labelLayout) {
	Ttk_DrawLayout(lframePtr->label.labelLayout, lframePtr->core.state, d);
    }
}

/* +++ Labelframe geometry manager hooks.
 */

/* LabelframePlaceSlaves --
/* LabelframePlaceContent --
 * 	Sets the position and size of the labelwidget.
 */
static void LabelframePlaceSlaves(void *recordPtr)
static void LabelframePlaceContent(void *recordPtr)
{
    Labelframe *lframe = (Labelframe *)recordPtr;

    if (Ttk_NumberSlaves(lframe->label.mgr) == 1) {
    if (Ttk_NumberContent(lframe->label.mgr) == 1) {
	Ttk_Box b;
	LabelframeDoLayout(recordPtr);
	b = lframe->label.labelParcel;
	/* ASSERT: slave #0 is lframe->label.labelWidget */
	Ttk_PlaceSlave(lframe->label.mgr, 0, b.x,b.y,b.width,b.height);
	/* ASSERT: content #0 is lframe->label.labelWidget */
	Ttk_PlaceContent(lframe->label.mgr, 0, b.x,b.y,b.width,b.height);
    }
}

static int LabelRequest(void *managerData, TkSizeT index, int width, int height)
static int LabelRequest(
{
    (void)managerData;
    (void)index;
    (void)width;
    TCL_UNUSED(void *),
    TCL_UNUSED(TkSizeT),
    TCL_UNUSED(int),
    TCL_UNUSED(int))
    (void)height;

{
    return 1;
}

/* LabelRemoved --
 * 	Unset the -labelwidget option.
 *
 * <<NOTE-LABELREMOVED>>:
 * 	This routine is also called when the widget voluntarily forgets
 * 	the slave in LabelframeConfigure.
 * 	the window in LabelframeConfigure.
 */
static void LabelRemoved(void *managerData, TkSizeT slaveIndex)
static void LabelRemoved(
    void *managerData,
    TCL_UNUSED(TkSizeT))
{
    Labelframe *lframe = (Labelframe *)managerData;
    (void)slaveIndex;

    lframe->label.labelWidget = 0;
}

static Ttk_ManagerSpec LabelframeManagerSpec = {
    { "labelframe", Ttk_GeometryRequestProc, Ttk_LostSlaveProc },
    { "labelframe", Ttk_GeometryRequestProc, Ttk_LostContentProc },
    LabelframeSize,
    LabelframePlaceSlaves,
    LabelframePlaceContent,
    LabelRequest,
    LabelRemoved
};

/* LabelframeInitialize --
 * 	Initialization hook.
 */
static void LabelframeInitialize(Tcl_Interp *dummy, void *recordPtr)
static void LabelframeInitialize(
    TCL_UNUSED(Tcl_Interp *),
    void *recordPtr)
{
    Labelframe *lframe = (Labelframe *)recordPtr;
    (void)dummy;

    lframe->label.mgr = Ttk_CreateManager(
	&LabelframeManagerSpec, lframe, lframe->core.tkwin);
    lframe->label.labelWidget = 0;
    lframe->label.labelLayout = 0;
    lframe->label.labelParcel = Ttk_MakeBox(-1,-1,-1,-1);
}
599
600
601
602
603
604
605
606
607


608
609
610
611
612
613
614

615
616
617
618
619
620
621
602
603
604
605
606
607
608


609
610
611
612
613
614
615
616

617
618
619
620
621
622
623
624







-
-
+
+






-
+







    if (FrameConfigure(interp, recordPtr, mask) != TCL_OK) {
	return TCL_ERROR;
    }

    /* Update -labelwidget changes, if any:
     */
    if (mask & LABELWIDGET_CHANGED) {
	if (Ttk_NumberSlaves(lframePtr->label.mgr) == 1) {
	    Ttk_ForgetSlave(lframePtr->label.mgr, 0);
	if (Ttk_NumberContent(lframePtr->label.mgr) == 1) {
	    Ttk_ForgetContent(lframePtr->label.mgr, 0);
	    /* Restore labelWidget field (see <<NOTE-LABELREMOVED>>)
	     */
	    lframePtr->label.labelWidget = labelWidget;
	}

	if (labelWidget) {
	    Ttk_InsertSlave(lframePtr->label.mgr, 0, labelWidget, NULL);
		Ttk_InsertContent(lframePtr->label.mgr, 0, labelWidget, NULL);
	    RaiseLabelWidget(lframePtr);
	}
    }

    if (mask & GEOMETRY_CHANGED) {
	Ttk_ManagerSizeChanged(lframePtr->label.mgr);
	Ttk_ManagerLayoutChanged(lframePtr->label.mgr);

Changes to generic/ttk/ttkImage.c.

1
2
3
4
5


6
7
8
9
10
11
12
1
2
3


4
5
6
7
8
9
10
11
12



-
-
+
+







/*
 *	Image specifications and image element factory.
 *
 * Copyright (C) 2004 Pat Thoyts <[email protected]>
 * Copyright (C) 2004 Joe English
 * Copyright © 2004 Pat Thoyts <[email protected]>
 * Copyright © 2004 Joe English
 *
 * An imageSpec is a multi-element list; the first element
 * is the name of the default image to use, the remainder of the
 * list is a sequence of statespec/imagename options as per
 * [style map].
 */

259
260
261
262
263
264
265
266

267
268
269
270
271
272
273
274
275
276

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

266
267
268
269
270
271
272
273
274
275

276
277
278
279
280
281
282
283







-
+









-
+







    Ttk_ImageSpec *imageSpec;	/* Image(s) to use */
    int minWidth;		/* Minimum width; overrides image width */
    int minHeight;		/* Minimum width; overrides image width */
    Ttk_Sticky sticky;		/* -stickiness specification */
    Ttk_Padding border;		/* Fixed border region */
    Ttk_Padding padding;	/* Internal padding */

#if TILE_07_COMPAT
#ifdef TILE_07_COMPAT
    Ttk_ResourceCache cache;	/* Resource cache for images */
    Ttk_StateMap imageMap;	/* State-based lookup table for images */
#endif
} ImageData;

static void FreeImageData(void *clientData)
{
    ImageData *imageData = (ImageData *)clientData;
    if (imageData->imageSpec)	{ TtkFreeImageSpec(imageData->imageSpec); }
#if TILE_07_COMPAT
#ifdef TILE_07_COMPAT
    if (imageData->imageMap)	{ Tcl_DecrRefCount(imageData->imageMap); }
#endif
    ckfree(clientData);
}

static void ImageElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
307
308
309
310
311
312
313
314

315
316
317
318
319
320
321
307
308
309
310
311
312
313

314
315
316
317
318
319
320
321







-
+







{
    ImageData *imageData = (ImageData *)clientData;
    Tk_Image image = 0;
    int imgWidth, imgHeight;
    Ttk_Box src, dst;
    (void)elementRecord;

#if TILE_07_COMPAT
#ifdef TILE_07_COMPAT
    if (imageData->imageMap) {
	Tcl_Obj *imageObj = Ttk_StateMapLookup(NULL,imageData->imageMap,state);
	if (imageObj) {
	    image = Ttk_UseImage(imageData->cache, tkwin, imageObj);
	}
    }
    if (!image) {
379
380
381
382
383
384
385
386

387
388
389
390
391
392
393
394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
379
380
381
382
383
384
385

386
387
388
389
390
391
392
393
394
395
396
397
398
399
400

401
402
403
404
405
406
407
408







-
+














-
+







    }

    imageData = (ImageData *)ckalloc(sizeof(*imageData));
    imageData->imageSpec = imageSpec;
    imageData->minWidth = imageData->minHeight = -1;
    imageData->sticky = TTK_FILL_BOTH;
    imageData->border = imageData->padding = Ttk_UniformPadding(0);
#if TILE_07_COMPAT
#ifdef TILE_07_COMPAT
    imageData->cache = Ttk_GetResourceCache(interp);
    imageData->imageMap = 0;
#endif

    for (i = 1; i < objc; i += 2) {
	int option;

	if (i == objc - 1) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "Value for %s missing", Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TTK", "IMAGE", "VALUE", NULL);
	    goto error;
	}

#if TILE_07_COMPAT
#ifdef TILE_07_COMPAT
	if (!strcmp("-map", Tcl_GetString(objv[i]))) {
	    imageData->imageMap = objv[i+1];
	    Tcl_IncrRefCount(imageData->imageMap);
	    continue;
	}
#endif

Changes to generic/ttk/ttkInit.c.

1
2

3
4
5
6
7
8
9
1

2
3
4
5
6
7
8
9

-
+







/*
 * Copyright (c) 2003, Joe English
 * Copyright © 2003 Joe English
 *
 * Ttk package: initialization routine and miscellaneous utilities.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
120
121
122
123
124
125
126






















127
128
129
130
131
132
133







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







	case TTK_COMPAT_STATE_ACTIVE:
	    SETFLAGS(TTK_STATE_ACTIVE);
	    break;
    }
#   undef SETFLAGS
}

/* TtkSendVirtualEvent --
 * 	Send a virtual event notification to the specified target window.
 * 	Equivalent to "event generate $tgtWindow <<$eventName>>"
 *
 * 	Note that we use Tk_QueueWindowEvent, not Tk_HandleEvent,
 * 	so this routine does not reenter the interpreter.
 */
void TtkSendVirtualEvent(Tk_Window tgtWin, const char *eventName)
{
    union {XEvent general; XVirtualEvent 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)
{
289
290
291
292
293
294
295

296


297
298
299
300
301
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282







+

+
+






    RegisterElements(interp);
    RegisterWidgets(interp);
    RegisterThemes(interp);

    Ttk_PlatformInit(interp);

#ifndef TK_NO_DEPRECATED
    Tcl_PkgProvideEx(interp, "Ttk", TTK_PATCH_LEVEL, (void *)&ttkStubs);
#endif
    Tcl_PkgProvideEx(interp, "ttk", TTK_PATCH_LEVEL, (void *)&ttkStubs);

    return TCL_OK;
}

/*EOF*/

Changes to generic/ttk/ttkLabel.c.

565
566
567
568
569
570
571

572
573





574
575
576
577
578
579
580
581
582
583
584
585
565
566
567
568
569
570
571
572


573
574
575
576
577
578
579
580


581
582
583
584
585
586
587







+
-
-
+
+
+
+
+



-
-







    if (c->compound != TTK_COMPOUND_TEXT)
	ImageCleanup(&c->image);
    if (c->compound != TTK_COMPOUND_IMAGE)
	TextCleanup(&c->text);
}

static void LabelElementSize(
    TCL_UNUSED(void *),
    void *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 *))
{
    LabelElement *label = (LabelElement *)elementRecord;
    int textReqWidth = 0;
    (void)dummy;
    (void)paddingPtr;

    LabelSetup(label, tkwin, 0);

    *heightPtr = label->totalHeight;

    /* Requested width based on -width option, not actual text width:
     */
624
625
626
627
628
629
630

631
632





633
634
635
636
637
638
639
640
641
642
643
626
627
628
629
630
631
632
633


634
635
636
637
638
639
640
641

642
643
644
645
646
647
648







+
-
-
+
+
+
+
+



-







    Ttk_Box textBox =
	Ttk_PlaceBox(&b, l->text.width, l->text.height, textSide, 0);
    ImageDraw(&l->image,tkwin,d,imageBox,state);
    TextDraw(&l->text,tkwin,d,textBox);
}

static void LabelElementDraw(
    TCL_UNUSED(void *),
    void *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)
{
    LabelElement *l = (LabelElement *)elementRecord;
    Tk_Anchor anchor = TK_ANCHOR_CENTER;
    (void)dummy;

    LabelSetup(l, tkwin, state);

    /*
     * Adjust overall parcel based on -anchor:
     */
    Tk_GetAnchorFromObj(NULL, l->text.anchorObj, &anchor);

Changes to generic/ttk/ttkLayout.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





-
+







/*
 * ttkLayout.c --
 *
 * Generic layout processing.
 *
 * Copyright (c) 2003 Joe English.  Freely redistributable.
 * Copyright © 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)
32
33
34
35
36
37
38
39
40
41
42




43
44
45
46
47
48
49
32
33
34
35
36
37
38




39
40
41
42
43
44
45
46
47
48
49







-
-
-
-
+
+
+
+







}

Tcl_Obj *
Ttk_NewBoxObj(Ttk_Box box)
{
    Tcl_Obj *result[4];

    result[0] = Tcl_NewIntObj(box.x);
    result[1] = Tcl_NewIntObj(box.y);
    result[2] = Tcl_NewIntObj(box.width);
    result[3] = Tcl_NewIntObj(box.height);
    result[0] = Tcl_NewWideIntObj(box.x);
    result[1] = Tcl_NewWideIntObj(box.y);
    result[2] = Tcl_NewWideIntObj(box.width);
    result[3] = Tcl_NewWideIntObj(box.height);

    return Tcl_NewListObj(4, result);
}

/*
 * packTop, packBottom, packLeft, packRight --
 * 	Carve out a parcel of the specified height (resp width)
805
806
807
808
809
810
811
812

813
814
815
816
817
818
819
805
806
807
808
809
810
811

812
813
814
815
816
817
818
819







-
+







	 * In Ttk_ParseLayoutTemplate, default -sticky is "nsew", so always
	 * include this even if no sticky bits are set.
	 */

	APPENDSTR("-sticky");
	APPENDOBJ(Ttk_NewStickyObj(flags & _TTK_MASK_STICK));

	/* @@@ Check again: are these necessary? */
	/* @@@ Check again: are these necessary? Can't see any effect! */
	if (flags & TTK_BORDER)	{ APPENDSTR("-border"); APPENDSTR("1"); }
	if (flags & TTK_UNIT) 	{ APPENDSTR("-unit"); APPENDSTR("1"); }

	if (node->child) {
	    APPENDSTR("-children");
	    APPENDOBJ(Ttk_UnparseLayoutTemplate(node->child));
	}

Changes to generic/ttk/ttkManager.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14


15
16
17
18
19


20
21

22
23

24
25
26
27
28
29

30
31

32
33
34
35

36
37
38
39



40
41

42
43
44
45
46
47
48

49
50

51
52

53
54

55
56

57
58
59
60
61
62

63
64
65


66
67
68
69
70
71
72
1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17


18
19
20

21
22

23
24
25
26
27
28

29
30

31
32
33
34

35
36



37
38
39
40

41
42
43
44
45
46
47

48
49

50
51

52
53

54
55

56
57
58
59
60
61

62
63


64
65
66
67
68
69
70
71
72












-
-
+
+



-
-
+
+

-
+

-
+





-
+

-
+



-
+

-
-
-
+
+
+

-
+






-
+

-
+

-
+

-
+

-
+





-
+

-
-
+
+







/*
 * Copyright 2005, Joe English.  Freely redistributable.
 *
 * Support routines for geometry managers.
 */

#include "tkInt.h"
#include "ttkManager.h"

/*------------------------------------------------------------------------
 * +++ The Geometry Propagation Dance.
 *
 * When a slave window requests a new size or some other parameter changes,
 * the manager recomputes the required size for the master window and calls
 * When a content window requests a new size or some other parameter changes,
 * the manager recomputes the required size for the container window and calls
 * Tk_GeometryRequest().  This is scheduled as an idle handler so multiple
 * updates can be processed as a single batch.
 *
 * If all goes well, the master's manager will process the request
 * (and so on up the chain to the toplevel window), and the master
 * If all goes well, the container's manager will process the request
 * (and so on up the chain to the toplevel window), and the container
 * window will eventually receive a <Configure> event.  At this point
 * it recomputes the size and position of all slaves and places them.
 * it recomputes the size and position of all content windows and places them.
 *
 * If all does not go well, however, the master's request may be ignored
 * If all does not go well, however, the container's request may be ignored
 * (typically because the top-level window has a fixed, user-specified size).
 * Tk doesn't provide any notification when this happens; to account for this,
 * we also schedule an idle handler to call the layout procedure
 * after making a geometry request.
 *
 * +++ Slave removal <<NOTE-LOSTSLAVE>>.
 * +++ Content window removal <<NOTE-LOSTCONTENT>>.
 *
 * There are three conditions under which a slave is removed:
 * There are three conditions under which a content window is removed:
 *
 * (1) Another GM claims control
 * (2) Manager voluntarily relinquishes control
 * (3) Slave is destroyed
 * (3) Content window is destroyed
 *
 * In case (1), Tk calls the manager's lostSlaveProc.
 * Case (2) is performed by calling Tk_ManageGeometry(slave,NULL,0);
 * in this case Tk does _not_ call the LostSlaveProc (documented behavior).
 * In case (1), Tk calls the manager's lostContentProc.
 * Case (2) is performed by calling Tk_ManageGeometry(window,NULL,0);
 * in this case Tk does _not_ call the lostContentProc (documented behavior).
 * Tk doesn't handle case (3) either; to account for that we
 * register an event handler on the slave widget to track <Destroy> events.
 * register an event handler on the content window to track <Destroy> events.
 */

/* ++ Data structures.
 */
typedef struct
{
    Tk_Window 		slaveWindow;
    Tk_Window 		window;
    Ttk_Manager 	*manager;
    void 		*slaveData;
    void 		*data;
    unsigned		flags;
} Ttk_Slave;
} Ttk_Content;

/* slave->flags bits:
/* content->flags bits:
 */
#define SLAVE_MAPPED 		0x1	/* slave to be mapped when master is */
#define CONTENT_MAPPED 	0x1	/* content windows to be mapped when container is */

struct TtkManager_
{
    Ttk_ManagerSpec	*managerSpec;
    void 		*managerData;
    Tk_Window   	masterWindow;
    Tk_Window   	window;
    unsigned		flags;
    TkSizeT 	 	nSlaves;
    Ttk_Slave 		**slaves;
    TkSizeT 	 	nContent;
    Ttk_Content 		**content;
};

/* manager->flags bits:
 */
#define MGR_UPDATE_PENDING	0x1
#define MGR_RESIZE_REQUIRED	0x2
#define MGR_RELAYOUT_REQUIRED	0x4
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98

99
100
101
102
103
104
105

106
107
108
109

110
111
112
113
114
115
116
83
84
85
86
87
88
89

90
91
92
93
94
95
96
97

98
99
100
101
102
103
104

105
106
107
108

109
110
111
112
113
114
115
116







-
+







-
+






-
+



-
+







	Tcl_DoWhenIdle(ManagerIdleProc, mgr);
	mgr->flags |= MGR_UPDATE_PENDING;
    }
    mgr->flags |= flags;
}

/* ++ RecomputeSize --
 * 	Recomputes the required size of the master window,
 * 	Recomputes the required size of the container window,
 * 	makes geometry request.
 */
static void RecomputeSize(Ttk_Manager *mgr)
{
    int width = 1, height = 1;

    if (mgr->managerSpec->RequestedSize(mgr->managerData, &width, &height)) {
	Tk_GeometryRequest(mgr->masterWindow, width, height);
	Tk_GeometryRequest(mgr->window, width, height);
	ScheduleUpdate(mgr, MGR_RELAYOUT_REQUIRED);
    }
    mgr->flags &= ~MGR_RESIZE_REQUIRED;
}

/* ++ RecomputeLayout --
 * 	Recompute geometry of all slaves.
 * 	Recompute geometry of all content windows.
 */
static void RecomputeLayout(Ttk_Manager *mgr)
{
    mgr->managerSpec->PlaceSlaves(mgr->managerData);
    mgr->managerSpec->PlaceContent(mgr->managerData);
    mgr->flags &= ~MGR_RELAYOUT_REQUIRED;
}

/* ++ ManagerIdleProc --
 * 	DoWhenIdle procedure for deferred updates.
 */
static void ManagerIdleProc(ClientData clientData)
131
132
133
134
135
136
137
138
139


140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156




157
158
159
160
161
162
163



164
165
166
167
168
169
170
171



172
173
174

175
176

177
178
179


180
181
182
183
184

185
186
187
188


189
190

191
192
193
194
195




196
197

198
199
200

201
202

203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218



219
220
221
222

223
224
225
226
227
228
229
230

231
232
233


234
235
236


237
238
239
240
241
242
243
244
245

246
247
248
249


250
251

252
253
254


255
256
257

258
259
260
261

262
263
264


265
266
267


268
269
270
271
272
273


274
275
276
277
278

279
280

281
282

283
284
285
286
287

288
289
290
291
292
293



294
295
296
297
298
299

300
301
302
303


304
305

306
307
308
309
310
311
312
313
314

315
316
317
318
319



320
321
322


323
324
325
326
327
328

329
330
331

332
333
334

335
336
337
338
339
340
341
342


343
344
345


346
347
348


349
350
351
352


353
354

355
356
357
358



359
360
361
362


363
364
365
366

367
368
369


370
371
372
373
374
375





376
377
378
379
380


381
382

383
384
385
386



387
388

389
390

391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408

409
410

411
412

413
414

415
416

417
418

419
420
421
422
423
424
425
426


427
428

429
430
431
432


433
434
435
436
437
438
439



440
441
442
443
444
445
446

447
448
449
450
451

452
453
454
455
456
457


458
459
460
461


462
463
464

465
466
467
468

469
470
471
472
473



474
475
476
477


478
479
480

481
482
483
484
485
486


487
488
489
490
491


492
493

494
495

496
497
498
499

500
501
502
503
504

505
506
507
508

509
510

511
512
513
514
515
516
517
518



519
520
521
522
523




524
525
526
527

528
529

530
531

532
533
534
535
536
537
538
539
540
541
542
543
544
545
546


547
548
549
550
131
132
133
134
135
136
137


138
139
140
141
142
143
144
145
146
147
148
149
150
151
152




153
154
155
156
157
158
159
160



161
162
163
164
165
166
167
168



169
170
171
172


173
174

175
176


177
178
179
180
181
182

183
184
185


186
187
188

189
190




191
192
193
194
195

196
197
198

199
200

201
202
203
204
205
206
207
208

209
210
211
212
213
214



215
216
217
218
219
220

221
222
223
224
225
226
227
228

229
230


231
232
233


234
235
236
237
238
239
240
241
242
243

244
245
246


247
248
249

250
251


252
253
254
255

256
257
258
259

260
261


262
263
264


265
266
267
268
269
270


271
272
273
274
275
276

277
278

279
280

281
282
283
284
285

286
287
288
289



290
291
292
293
294
295
296
297

298
299
300


301
302
303

304
305
306
307
308
309
310
311
312

313
314
315



316
317
318
319


320
321
322
323
324
325
326

327
328
329

330
331
332

333
334
335
336
337
338
339


340
341
342


343
344
345


346
347
348
349


350
351
352

353
354



355
356
357
358
359


360
361
362
363
364

365
366


367
368
369





370
371
372
373
374
375
376
377


378
379
380

381
382



383
384
385
386

387
388

389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406

407
408

409
410

411
412

413
414

415
416

417
418
419
420
421
422
423


424
425
426

427
428
429


430
431
432
433
434
435



436
437
438
439
440
441
442
443
444

445
446
447
448


449
450
451
452
453


454
455

456


457
458
459
460

461
462
463
464

465
466
467



468
469
470
471
472


473
474
475
476

477
478
479
480
481


482
483
484
485
486


487
488
489

490
491

492
493
494
495

496
497
498
499
500

501
502
503
504

505
506

507
508
509
510
511
512



513
514
515
516




517
518
519
520
521
522
523

524
525

526
527

528
529
530
531
532
533
534
535
536
537
538
539
540
541


542
543
544
545
546
547







-
-
+
+













-
-
-
-
+
+
+
+




-
-
-
+
+
+





-
-
-
+
+
+

-
-
+

-
+

-
-
+
+




-
+


-
-
+
+

-
+

-
-
-
-
+
+
+
+

-
+


-
+

-
+







-
+





-
-
-
+
+
+



-
+







-
+

-
-
+
+

-
-
+
+








-
+


-
-
+
+

-
+

-
-
+
+


-
+



-
+

-
-
+
+

-
-
+
+




-
-
+
+




-
+

-
+

-
+




-
+



-
-
-
+
+
+





-
+


-
-
+
+

-
+








-
+


-
-
-
+
+
+

-
-
+
+





-
+


-
+


-
+






-
-
+
+

-
-
+
+

-
-
+
+


-
-
+
+

-
+

-
-
-
+
+
+


-
-
+
+



-
+

-
-
+
+

-
-
-
-
-
+
+
+
+
+



-
-
+
+

-
+

-
-
-
+
+
+

-
+

-
+

















-
+

-
+

-
+

-
+

-
+

-
+






-
-
+
+

-
+


-
-
+
+




-
-
-
+
+
+






-
+



-
-
+




-
-
+
+
-

-
-
+
+


-
+



-
+


-
-
-
+
+
+


-
-
+
+


-
+




-
-
+
+



-
-
+
+

-
+

-
+



-
+




-
+



-
+

-
+





-
-
-
+
+
+

-
-
-
-
+
+
+
+



-
+

-
+

-
+













-
-
+
+




}

/*------------------------------------------------------------------------
 * +++ Event handlers.
 */

/* ++ ManagerEventHandler --
 * 	Recompute slave layout when master widget is resized.
 * 	Keep the slave's map state in sync with the master's.
 * 	Recompute content layout when container widget is resized.
 * 	Keep the content's map state in sync with the container's.
 */
static const int ManagerEventMask = StructureNotifyMask;
static void ManagerEventHandler(ClientData clientData, XEvent *eventPtr)
{
    Ttk_Manager *mgr = (Ttk_Manager *)clientData;
    TkSizeT i;

    switch (eventPtr->type)
    {
	case ConfigureNotify:
	    RecomputeLayout(mgr);
	    break;
	case MapNotify:
	    for (i = 0; i < mgr->nSlaves; ++i) {
		Ttk_Slave *slave = mgr->slaves[i];
		if (slave->flags & SLAVE_MAPPED) {
		    Tk_MapWindow(slave->slaveWindow);
	    for (i = 0; i < mgr->nContent; ++i) {
		Ttk_Content *content = mgr->content[i];
		if (content->flags & CONTENT_MAPPED) {
		    Tk_MapWindow(content->window);
		}
	    }
	    break;
	case UnmapNotify:
	    for (i = 0; i < mgr->nSlaves; ++i) {
		Ttk_Slave *slave = mgr->slaves[i];
		Tk_UnmapWindow(slave->slaveWindow);
	    for (i = 0; i < mgr->nContent; ++i) {
		Ttk_Content *content = mgr->content[i];
		Tk_UnmapWindow(content->window);
	    }
	    break;
    }
}

/* ++ SlaveEventHandler --
 * 	Notifies manager when a slave is destroyed
 * 	(see <<NOTE-LOSTSLAVE>>).
/* ++ ContentLostEventHandler --
 * 	Notifies manager when a content window is destroyed
 * 	(see <<NOTE-LOSTCONTENT>>).
 */
static const unsigned SlaveEventMask = StructureNotifyMask;
static void SlaveEventHandler(ClientData clientData, XEvent *eventPtr)
static void ContentLostEventHandler(void *clientData, XEvent *eventPtr)
{
    Ttk_Slave *slave = (Ttk_Slave *)clientData;
    Ttk_Content *content = (Ttk_Content *)clientData;
    if (eventPtr->type == DestroyNotify) {
	slave->manager->managerSpec->tkGeomMgr.lostSlaveProc(
	    slave->manager, slave->slaveWindow);
	content->manager->managerSpec->tkGeomMgr.lostContentProc(
	    content->manager, content->window);
    }
}

/*------------------------------------------------------------------------
 * +++ Slave initialization and cleanup.
 * +++ Content initialization and cleanup.
 */

static Ttk_Slave *NewSlave(
    Ttk_Manager *mgr, Tk_Window slaveWindow, void *slaveData)
static Ttk_Content *NewContent(
    Ttk_Manager *mgr, Tk_Window window, void *data)
{
    Ttk_Slave *slave = (Ttk_Slave *)ckalloc(sizeof(*slave));
    Ttk_Content *content = (Ttk_Content *)ckalloc(sizeof(Ttk_Content));

    slave->slaveWindow = slaveWindow;
    slave->manager = mgr;
    slave->flags = 0;
    slave->slaveData = slaveData;
    content->window = window;
    content->manager = mgr;
    content->flags = 0;
    content->data = data;

    return slave;
    return content;
}

static void DeleteSlave(Ttk_Slave *slave)
static void DeleteContent(Ttk_Content *content)
{
    ckfree(slave);
    ckfree(content);
}

/*------------------------------------------------------------------------
 * +++ Manager initialization and cleanup.
 */

Ttk_Manager *Ttk_CreateManager(
    Ttk_ManagerSpec *managerSpec, void *managerData, Tk_Window masterWindow)
    Ttk_ManagerSpec *managerSpec, void *managerData, Tk_Window window)
{
    Ttk_Manager *mgr = (Ttk_Manager *)ckalloc(sizeof(*mgr));

    mgr->managerSpec 	= managerSpec;
    mgr->managerData	= managerData;
    mgr->masterWindow	= masterWindow;
    mgr->nSlaves 	= 0;
    mgr->slaves 	= NULL;
    mgr->window	= window;
    mgr->nContent 	= 0;
    mgr->content 	= NULL;
    mgr->flags  	= 0;

    Tk_CreateEventHandler(
	mgr->masterWindow, ManagerEventMask, ManagerEventHandler, mgr);
	mgr->window, ManagerEventMask, ManagerEventHandler, mgr);

    return mgr;
}

void Ttk_DeleteManager(Ttk_Manager *mgr)
{
    Tk_DeleteEventHandler(
	mgr->masterWindow, ManagerEventMask, ManagerEventHandler, mgr);
	mgr->window, ManagerEventMask, ManagerEventHandler, mgr);

    while (mgr->nSlaves > 0) {
	Ttk_ForgetSlave(mgr, mgr->nSlaves - 1);
    while (mgr->nContent > 0) {
	Ttk_ForgetContent(mgr, mgr->nContent - 1);
    }
    if (mgr->slaves) {
	ckfree(mgr->slaves);
    if (mgr->content) {
	ckfree(mgr->content);
    }

    Tcl_CancelIdleCall(ManagerIdleProc, mgr);

    ckfree(mgr);
}

/*------------------------------------------------------------------------
 * +++ Slave management.
 * +++ Content window management.
 */

/* ++ InsertSlave --
 * 	Adds slave to the list of managed windows.
/* ++ InsertContent --
 * 	Adds content to the list of managed windows.
 */
static void InsertSlave(Ttk_Manager *mgr, Ttk_Slave *slave, TkSizeT index)
static void InsertContent(Ttk_Manager *mgr, Ttk_Content *content, TkSizeT index)
{
    TkSizeT endIndex = mgr->nSlaves++;
    mgr->slaves = (Ttk_Slave **)ckrealloc(mgr->slaves, mgr->nSlaves * sizeof(Ttk_Slave *));
    TkSizeT endIndex = mgr->nContent++;
    mgr->content = (Ttk_Content **)ckrealloc(mgr->content, mgr->nContent * sizeof(Ttk_Content *));

    while (endIndex > index) {
	mgr->slaves[endIndex] = mgr->slaves[endIndex - 1];
	mgr->content[endIndex] = mgr->content[endIndex - 1];
	--endIndex;
    }

    mgr->slaves[index] = slave;
    mgr->content[index] = content;

    Tk_ManageGeometry(slave->slaveWindow,
	&mgr->managerSpec->tkGeomMgr, (ClientData)mgr);
    Tk_ManageGeometry(content->window,
	&mgr->managerSpec->tkGeomMgr, mgr);

    Tk_CreateEventHandler(slave->slaveWindow,
	SlaveEventMask, SlaveEventHandler, (ClientData)slave);
    Tk_CreateEventHandler(content->window,
	StructureNotifyMask, ContentLostEventHandler, content);

    ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
}

/* RemoveSlave --
 * 	Unmanage and delete the slave.
/* RemoveContent --
 * 	Unmanage and delete the content window.
 *
 * NOTES/ASSUMPTIONS:
 *
 * [1] It's safe to call Tk_UnmapWindow / Tk_UnmaintainGeometry even if this
 * routine is called from the slave's DestroyNotify event handler.
 * routine is called from the content window's DestroyNotify event handler.
 */
static void RemoveSlave(Ttk_Manager *mgr, TkSizeT index)
static void RemoveContent(Ttk_Manager *mgr, TkSizeT index)
{
    Ttk_Slave *slave = mgr->slaves[index];
    Ttk_Content *content = mgr->content[index];
    TkSizeT i;

    /* Notify manager:
     */
    mgr->managerSpec->SlaveRemoved(mgr->managerData, index);
    mgr->managerSpec->ContentRemoved(mgr->managerData, index);

    /* Remove from array:
     */
    --mgr->nSlaves;
    for (i = index ; i < mgr->nSlaves; ++i) {
	mgr->slaves[i] = mgr->slaves[i+1];
    --mgr->nContent;
    for (i = index ; i < mgr->nContent; ++i) {
	mgr->content[i] = mgr->content[i+1];
    }

    /* Clean up:
     */
    Tk_DeleteEventHandler(
	slave->slaveWindow, SlaveEventMask, SlaveEventHandler, slave);
	content->window, StructureNotifyMask, ContentLostEventHandler, content);

    /* Note [1] */
    Tk_UnmaintainGeometry(slave->slaveWindow, mgr->masterWindow);
    Tk_UnmapWindow(slave->slaveWindow);
    Tk_UnmaintainGeometry(content->window, mgr->window);
    Tk_UnmapWindow(content->window);

    DeleteSlave(slave);
    DeleteContent(content);

    ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
}

/*------------------------------------------------------------------------
 * +++ Tk_GeomMgr hooks.
 */

void Ttk_GeometryRequestProc(ClientData clientData, Tk_Window slaveWindow)
void Ttk_GeometryRequestProc(ClientData clientData, Tk_Window window)
{
    Ttk_Manager *mgr = (Ttk_Manager *)clientData;
    int slaveIndex = Ttk_SlaveIndex(mgr, slaveWindow);
    int reqWidth = Tk_ReqWidth(slaveWindow);
    int reqHeight= Tk_ReqHeight(slaveWindow);
    TkSizeT index = Ttk_ContentIndex(mgr, window);
    int reqWidth = Tk_ReqWidth(window);
    int reqHeight= Tk_ReqHeight(window);

    if (mgr->managerSpec->SlaveRequest(
		mgr->managerData, slaveIndex, reqWidth, reqHeight))
    if (mgr->managerSpec->ContentRequest(
		mgr->managerData, index, reqWidth, reqHeight))
    {
	ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
    }
}

void Ttk_LostSlaveProc(ClientData clientData, Tk_Window slaveWindow)
void Ttk_LostContentProc(ClientData clientData, Tk_Window window)
{
    Ttk_Manager *mgr = (Ttk_Manager *)clientData;
    int index = Ttk_SlaveIndex(mgr, slaveWindow);
    TkSizeT index = Ttk_ContentIndex(mgr, window);

    /* ASSERT: index >= 0 */
    RemoveSlave(mgr, index);
    RemoveContent(mgr, index);
}

/*------------------------------------------------------------------------
 * +++ Public API.
 */

/* ++ Ttk_InsertSlave --
 * 	Add a new slave window at the specified index.
/* ++ Ttk_InsertContent --
 * 	Add a new content window at the specified index.
 */
void Ttk_InsertSlave(
    Ttk_Manager *mgr, TkSizeT index, Tk_Window tkwin, void *slaveData)
void Ttk_InsertContent(
    Ttk_Manager *mgr, TkSizeT index, Tk_Window tkwin, void *data)
{
    Ttk_Slave *slave = NewSlave(mgr, tkwin, slaveData);
    InsertSlave(mgr, slave, index);
    Ttk_Content *content = NewContent(mgr, tkwin, data);
    InsertContent(mgr, content, index);
}

/* ++ Ttk_ForgetSlave --
 * 	Unmanage the specified slave.
/* ++ Ttk_ForgetContent --
 * 	Unmanage the specified content window.
 */
void Ttk_ForgetSlave(Ttk_Manager *mgr, TkSizeT slaveIndex)
void Ttk_ForgetContent(Ttk_Manager *mgr, TkSizeT index)
{
    Tk_Window slaveWindow = mgr->slaves[slaveIndex]->slaveWindow;
    RemoveSlave(mgr, slaveIndex);
    Tk_ManageGeometry(slaveWindow, NULL, 0);
    Tk_Window window = mgr->content[index]->window;
    RemoveContent(mgr, index);
    Tk_ManageGeometry(window, NULL, 0);
}

/* ++ Ttk_PlaceSlave --
 * 	Set the position and size of the specified slave window.
/* ++ Ttk_PlaceContent --
 * 	Set the position and size of the specified content window.
 *
 * NOTES:
 * 	Contrary to documentation, Tk_MaintainGeometry doesn't always
 * 	map the slave.
 * 	map the content window.
 */
void Ttk_PlaceSlave(
    Ttk_Manager *mgr, TkSizeT slaveIndex, int x, int y, int width, int height)
void Ttk_PlaceContent(
    Ttk_Manager *mgr, TkSizeT index, int x, int y, int width, int height)
{
    Ttk_Slave *slave = mgr->slaves[slaveIndex];
    Tk_MaintainGeometry(slave->slaveWindow,mgr->masterWindow,x,y,width,height);
    slave->flags |= SLAVE_MAPPED;
    if (Tk_IsMapped(mgr->masterWindow)) {
	Tk_MapWindow(slave->slaveWindow);
    Ttk_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_UnmapSlave --
 * 	Unmap the specified slave, but leave it managed.
/* ++ Ttk_UnmapContent --
 * 	Unmap the specified content window, but leave it managed.
 */
void Ttk_UnmapSlave(Ttk_Manager *mgr, TkSizeT slaveIndex)
void Ttk_UnmapContent(Ttk_Manager *mgr, TkSizeT index)
{
    Ttk_Slave *slave = mgr->slaves[slaveIndex];
    Tk_UnmaintainGeometry(slave->slaveWindow, mgr->masterWindow);
    slave->flags &= ~SLAVE_MAPPED;
    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 slave:
     * unmap the content window:
     */
    Tk_UnmapWindow(slave->slaveWindow);
    Tk_UnmapWindow(content->window);
}

/* LayoutChanged, SizeChanged --
 * 	Schedule a relayout, resp. resize request.
 */
void Ttk_ManagerLayoutChanged(Ttk_Manager *mgr)
{
    ScheduleUpdate(mgr, MGR_RELAYOUT_REQUIRED);
}

void Ttk_ManagerSizeChanged(Ttk_Manager *mgr)
{
    ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
}

/* +++ Accessors.
 */
TkSizeT Ttk_NumberSlaves(Ttk_Manager *mgr)
TkSizeT Ttk_NumberContent(Ttk_Manager *mgr)
{
    return mgr->nSlaves;
    return mgr->nContent;
}
void *Ttk_SlaveData(Ttk_Manager *mgr, TkSizeT slaveIndex)
void *Ttk_ContentData(Ttk_Manager *mgr, TkSizeT index)
{
    return mgr->slaves[slaveIndex]->slaveData;
    return mgr->content[index]->data;
}
Tk_Window Ttk_SlaveWindow(Ttk_Manager *mgr, TkSizeT slaveIndex)
Tk_Window Ttk_ContentWindow(Ttk_Manager *mgr, TkSizeT index)
{
    return mgr->slaves[slaveIndex]->slaveWindow;
    return mgr->content[index]->window;
}

/*------------------------------------------------------------------------
 * +++ Utility routines.
 */

/* ++ Ttk_SlaveIndex --
 * 	Returns the index of specified slave window, -1 if not found.
/* ++ Ttk_ContentIndex --
 * 	Returns the index of specified content window, -1 if not found.
 */
TkSizeT Ttk_SlaveIndex(Ttk_Manager *mgr, Tk_Window slaveWindow)
TkSizeT Ttk_ContentIndex(Ttk_Manager *mgr, Tk_Window window)
{
    TkSizeT index;
    for (index = 0; index < mgr->nSlaves; ++index)
	if (mgr->slaves[index]->slaveWindow == slaveWindow)
    for (index = 0; index < mgr->nContent; ++index)
	if (mgr->content[index]->window == window)
	    return index;
    return TCL_INDEX_NONE;
}

/* ++ Ttk_GetSlaveIndexFromObj(interp, mgr, objPtr, indexPtr) --
 * 	Return the index of the slave specified by objPtr.
 * 	Slaves may be specified as an integer index or
/* ++ 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_GetSlaveIndexFromObj(
int Ttk_GetContentIndexFromObj(
    Tcl_Interp *interp, Ttk_Manager *mgr, Tcl_Obj *objPtr, TkSizeT *indexPtr)
{
    const char *string = Tcl_GetString(objPtr);
    TkSizeT slaveIndex = 0;
    TkSizeT idx;
    TkSizeT index = 0;
    Tk_Window tkwin;

    /* Try interpreting as an integer first:
     */
    if (TkGetIntForIndex(objPtr, mgr->nSlaves - 1, 1, &idx) == TCL_OK) {
	slaveIndex = idx;
    if (TkGetIntForIndex(objPtr, mgr->nContent - 1, 1, &index) == TCL_OK) {
	if (index + 1 > mgr->nContent + 1) {
	if ((size_t)slaveIndex > (size_t)mgr->nSlaves) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"Slave index %d out of bounds", (int)slaveIndex));
	    Tcl_SetErrorCode(interp, "TTK", "SLAVE", "INDEX", NULL);
		"Managed window index %d out of bounds", (int)index));
	    Tcl_SetErrorCode(interp, "TTK", "MANAGED", "INDEX", NULL);
	    return TCL_ERROR;
	}
	*indexPtr = slaveIndex;
	*indexPtr = index;
	return TCL_OK;
    }

    /* Try interpreting as a slave window name;
    /* Try interpreting as a window name;
     */
    if ((*string == '.') &&
	    (tkwin = Tk_NameToWindow(interp, string, mgr->masterWindow))) {
	slaveIndex = Ttk_SlaveIndex(mgr, tkwin);
	if (slaveIndex == TCL_INDEX_NONE) {
	    (tkwin = Tk_NameToWindow(interp, string, mgr->window))) {
	index = Ttk_ContentIndex(mgr, tkwin);
	if (index == TCL_INDEX_NONE) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "%s is not managed by %s", string,
		    Tk_PathName(mgr->masterWindow)));
	    Tcl_SetErrorCode(interp, "TTK", "SLAVE", "MANAGER", NULL);
		    Tk_PathName(mgr->window)));
	    Tcl_SetErrorCode(interp, "TTK", "MANAGED", "MANAGER", NULL);
	    return TCL_ERROR;
	}
	*indexPtr = slaveIndex;
	*indexPtr = index;
	return TCL_OK;
    }

    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "Invalid slave specification %s", string));
    Tcl_SetErrorCode(interp, "TTK", "SLAVE", "SPEC", NULL);
	    "Invalid managed window specification %s", string));
    Tcl_SetErrorCode(interp, "TTK", "MANAGED", "SPEC", NULL);
    return TCL_ERROR;
}

/* ++ Ttk_ReorderSlave(mgr, fromIndex, toIndex) --
 * 	Change slave order.
/* ++ Ttk_ReorderContent(mgr, fromIndex, toIndex) --
 * 	Change content window order.
 */
void Ttk_ReorderSlave(Ttk_Manager *mgr, TkSizeT fromIndex, TkSizeT toIndex)
void Ttk_ReorderContent(Ttk_Manager *mgr, TkSizeT fromIndex, TkSizeT toIndex)
{
    Ttk_Slave *moved = mgr->slaves[fromIndex];
    Ttk_Content *moved = mgr->content[fromIndex];

    /* Shuffle down: */
    while (fromIndex > toIndex) {
	mgr->slaves[fromIndex] = mgr->slaves[fromIndex - 1];
	mgr->content[fromIndex] = mgr->content[fromIndex - 1];
	--fromIndex;
    }
    /* Or, shuffle up: */
    while (fromIndex < toIndex) {
	mgr->slaves[fromIndex] = mgr->slaves[fromIndex + 1];
	mgr->content[fromIndex] = mgr->content[fromIndex + 1];
	++fromIndex;
    }
    /* ASSERT: fromIndex == toIndex */
    mgr->slaves[fromIndex] = moved;
    mgr->content[fromIndex] = moved;

    /* Schedule a relayout.  In general, rearranging slaves
    /* Schedule a relayout.  In general, rearranging content
     * may also change the size:
     */
    ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
}

/* ++ Ttk_Maintainable(interp, slave, master) --
 * 	Utility routine.  Verifies that 'master' may be used to maintain
 *	the geometry of 'slave' via Tk_MaintainGeometry:
/* ++ Ttk_Maintainable(interp, window, container) --
 * 	Utility routine.  Verifies that 'container' may be used to maintain
 *	the geometry of 'window' via Tk_MaintainGeometry:
 *
 * 	+ 'master' is either 'slave's parent -OR-
 * 	+ 'master is a descendant of 'slave's parent.
 * 	+ 'slave' is not a toplevel window
 * 	+ 'slave' belongs to the same toplevel as 'master'
 * 	+ 'container' is either 'window's parent -OR-
 * 	+ 'container is a descendant of 'window's parent.
 * 	+ 'window' is not a toplevel window
 * 	+ 'window' belongs to the same toplevel as 'container'
 *
 * Returns: 1 if OK; otherwise 0, leaving an error message in 'interp'.
 */
int Ttk_Maintainable(Tcl_Interp *interp, Tk_Window slave, Tk_Window master)
int Ttk_Maintainable(Tcl_Interp *interp, Tk_Window window, Tk_Window container)
{
    Tk_Window ancestor = master, parent = Tk_Parent(slave);
    Tk_Window ancestor = container, parent = Tk_Parent(window);

    if (Tk_IsTopLevel(slave) || slave == master) {
    if (Tk_IsTopLevel(window) || window == container) {
	goto badWindow;
    }

    while (ancestor != parent) {
	if (Tk_IsTopLevel(ancestor)) {
	    goto badWindow;
	}
	ancestor = Tk_Parent(ancestor);
    }

    return 1;

badWindow:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf("can't add %s as slave of %s",
	    Tk_PathName(slave), Tk_PathName(master)));
    Tcl_SetObjResult(interp, Tcl_ObjPrintf("can't add %s as content of %s",
	    Tk_PathName(window), Tk_PathName(container)));
    Tcl_SetErrorCode(interp, "TTK", "GEOMETRY", "MAINTAINABLE", NULL);
    return 0;
}

Changes to generic/ttk/ttkManager.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
1

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18


19
20
21


22
23
24
25

26
27
28
29
30
31
32



33
34
35
36
37
38
39
40
41


42
43
44
45
46
47
48

49
50
51
52


53
54
55
56

57
58
59


60
61
62
63



64
65
66
67
68


69
70
71
72
73
74
75
76
77
78


79
80
81
82

83
84
85
86
87
88


89
90
91
92


93
94
95
96


97
98
99


100
101
102
103

-
+














-
+

-
-
+
+

-
-
+
+


-
+






-
-
-
+
+
+





+
-
-
+
+





-
+


+
-
-
+
+

+
-
+

+
-
-
+
+

+
-
-
-
+
+
+

+
-
-
+
+







+
-
-
+
+

+
-
+




+
-
-
+
+

+
-
-
+
+

+
-
-
+
+

-
-
+
+


/*
 * Copyright (c) 2005, Joe English.  Freely redistributable.
 * Copyright © 2005 Joe English.  Freely redistributable.
 *
 * Geometry manager utilities.
 */

#ifndef _TTKMANAGER
#define _TTKMANAGER

#include "ttkTheme.h"

typedef struct TtkManager_ Ttk_Manager;

/*
 * Geometry manager specification record:
 *
 * RequestedSize computes the requested size of the master window.
 * RequestedSize computes the requested size of the container window.
 *
 * PlaceSlaves sets the position and size of all managed slaves
 * by calling Ttk_PlaceSlave().
 * PlaceContent sets the position and size of all managed content windows
 * by calling Ttk_PlaceContent().
 *
 * SlaveRemoved() is called immediately before a slave is removed.
 * NB: the associated slave window may have been destroyed when this
 * ContentRemoved() is called immediately before a content window is removed.
 * NB: the associated content window may have been destroyed when this
 * routine is called.
 *
 * SlaveRequest() is called when a slave requests a size change.
 * ContentRequest() is called when a content window requests a size change.
 * It should return 1 if the request should propagate, 0 otherwise.
 */
typedef struct {			/* Manager hooks */
    Tk_GeomMgr tkGeomMgr;		/* "real" Tk Geometry Manager */

    int  (*RequestedSize)(void *managerData, int *widthPtr, int *heightPtr);
    void (*PlaceSlaves)(void *managerData);
    int  (*SlaveRequest)(void *managerData, TkSizeT slaveIndex, int w, int h);
    void (*SlaveRemoved)(void *managerData, TkSizeT slaveIndex);
    void (*PlaceContent)(void *managerData);
    int  (*ContentRequest)(void *managerData, TkSizeT index, int w, int h);
    void (*ContentRemoved)(void *managerData, TkSizeT index);
} Ttk_ManagerSpec;

/*
 * Default implementations for Tk_GeomMgr hooks:
 */
#define Ttk_LostSlaveProc Ttk_LostContentProc
MODULE_SCOPE void Ttk_GeometryRequestProc(ClientData, Tk_Window slave);
MODULE_SCOPE void Ttk_LostSlaveProc(ClientData, Tk_Window slave);
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 masterWindow);
	Ttk_ManagerSpec *, void *managerData, Tk_Window window);
MODULE_SCOPE void Ttk_DeleteManager(Ttk_Manager *);

#define  Ttk_InsertSlave Ttk_InsertContent
MODULE_SCOPE void Ttk_InsertSlave(
    Ttk_Manager *, TkSizeT position, Tk_Window, void *slaveData);
MODULE_SCOPE void Ttk_InsertContent(
    Ttk_Manager *, TkSizeT position, Tk_Window, void *clientData);

#define Ttk_ForgetSlave Ttk_ForgetContent
MODULE_SCOPE void Ttk_ForgetSlave(Ttk_Manager *, TkSizeT slaveIndex);
MODULE_SCOPE void Ttk_ForgetContent(Ttk_Manager *, TkSizeT index);

#define Ttk_ReorderSlave Ttk_ReorderContent
MODULE_SCOPE void Ttk_ReorderSlave(Ttk_Manager *, TkSizeT fromIndex, TkSizeT toIndex);
    /* Rearrange slave positions */
MODULE_SCOPE void Ttk_ReorderContent(Ttk_Manager *, TkSizeT fromIndex, TkSizeT toIndex);
    /* Rearrange content window positions */

#define Ttk_PlaceSlave Ttk_PlaceContent
MODULE_SCOPE void Ttk_PlaceSlave(
    Ttk_Manager *, TkSizeT slaveIndex, int x, int y, int width, int height);
    /* Position and map the slave */
MODULE_SCOPE void Ttk_PlaceContent(
    Ttk_Manager *, TkSizeT index, int x, int y, int width, int height);
    /* Position and map the content window */

#define Ttk_UnmapSlave Ttk_UnmapContent
MODULE_SCOPE void Ttk_UnmapSlave(Ttk_Manager *, TkSizeT slaveIndex);
    /* Unmap the slave */
MODULE_SCOPE void Ttk_UnmapContent(Ttk_Manager *, TkSizeT index);
    /* Unmap the content window */

MODULE_SCOPE void Ttk_ManagerSizeChanged(Ttk_Manager *);
MODULE_SCOPE void Ttk_ManagerLayoutChanged(Ttk_Manager *);
    /* Notify manager that size (resp. layout) needs to be recomputed */

/* Utilities:
 */
#define Ttk_SlaveIndex Ttk_ContentIndex
MODULE_SCOPE TkSizeT Ttk_SlaveIndex(Ttk_Manager *, Tk_Window);
    /* Returns: index in slave array of specified window, -1 if not found */
MODULE_SCOPE TkSizeT Ttk_ContentIndex(Ttk_Manager *, Tk_Window);
    /* Returns: index in content array of specified window, TCL_INDEX_NONE if not found */

#define Ttk_GetSlaveIndexFromObj Ttk_GetContentIndexFromObj
MODULE_SCOPE int Ttk_GetSlaveIndexFromObj(
MODULE_SCOPE int Ttk_GetContentIndexFromObj(
    Tcl_Interp *, Ttk_Manager *, Tcl_Obj *, TkSizeT *indexPtr);

/* Accessor functions:
 */
#define Ttk_NumberSlaves Ttk_NumberContent
MODULE_SCOPE TkSizeT Ttk_NumberSlaves(Ttk_Manager *);
    /* Returns: number of managed slaves */
MODULE_SCOPE TkSizeT Ttk_NumberContent(Ttk_Manager *);
    /* Returns: number of managed content windows */

#define Ttk_SlaveData Ttk_ContentData
MODULE_SCOPE void *Ttk_SlaveData(Ttk_Manager *, TkSizeT slaveIndex);
    /* Returns: client data associated with slave */
MODULE_SCOPE void *Ttk_ContentData(Ttk_Manager *, TkSizeT index);
    /* Returns: client data associated with content window */

#define Ttk_SlaveWindow Ttk_ContentWindow
MODULE_SCOPE Tk_Window Ttk_SlaveWindow(Ttk_Manager *, TkSizeT slaveIndex);
    /* Returns: slave window */
MODULE_SCOPE Tk_Window Ttk_ContentWindow(Ttk_Manager *, TkSizeT index);
    /* Returns: content window */

MODULE_SCOPE int Ttk_Maintainable(Tcl_Interp *, Tk_Window slave, Tk_Window master);
    /* Returns: 1 if master can manage slave; 0 otherwise leaving error msg */
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
1

2
3
4
5
6
7
8
9

-
+







/*
 * Copyright (c) 2004, Joe English
 * Copyright © 2004 Joe English
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
#include "ttkManager.h"

49
50
51
52
53
54
55
56

57
58
59
60
61
62

63
64

65
66

67
68
69
70
71

72
73
74
75
76
77
78

79
80

81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

102
103
104
105
106
107
108
49
50
51
52
53
54
55

56
57
58
59
60
61

62
63

64
65

66
67
68
69
70

71
72
73
74
75
76
77

78
79

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

101
102
103
104
105
106
107
108







-
+





-
+

-
+

-
+




-
+






-
+

-
+




















-
+







} Tab;

/* Two different option tables are used for tabs:
 * TabOptionSpecs is used to draw the tab, and only includes resources
 * relevant to the tab.
 *
 * PaneOptionSpecs includes additional options for child window placement
 * and is used to configure the slave.
 * and is used to configure the pane.
 */
static const Tk_OptionSpec TabOptionSpecs[] =
{
    {TK_OPTION_STRING_TABLE, "-state", "", "",
	"normal", TCL_INDEX_NONE, offsetof(Tab,state),
	0,(ClientData)TabStateStrings,0 },
	0, (void *)TabStateStrings, 0 },
    {TK_OPTION_STRING, "-text", "text", "Text", "",
	offsetof(Tab,textObj), TCL_INDEX_NONE, 0,0,GEOMETRY_CHANGED },
	offsetof(Tab,textObj), TCL_INDEX_NONE, 0, 0, GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-image", "image", "Image", NULL/*default*/,
	offsetof(Tab,imageObj), TCL_INDEX_NONE, TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
	offsetof(Tab,imageObj), TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, GEOMETRY_CHANGED },
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	NULL, offsetof(Tab,compoundObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,(void *)ttkCompoundStrings,GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-underline", "underline", "Underline", "-1",
	offsetof(Tab,underlineObj), TCL_INDEX_NONE, 0,0,GEOMETRY_CHANGED },
	offsetof(Tab,underlineObj), TCL_INDEX_NONE, 0, 0, GEOMETRY_CHANGED },
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0 }
};

static const Tk_OptionSpec PaneOptionSpecs[] =
{
    {TK_OPTION_STRING, "-padding", "padding", "Padding", "0",
	offsetof(Tab,paddingObj), TCL_INDEX_NONE, 0,0,GEOMETRY_CHANGED },
	offsetof(Tab,paddingObj), TCL_INDEX_NONE, 0, 0, GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-sticky", "sticky", "Sticky", "nsew",
	offsetof(Tab,stickyObj), TCL_INDEX_NONE, 0,0,GEOMETRY_CHANGED },
	offsetof(Tab,stickyObj), TCL_INDEX_NONE, 0, 0, GEOMETRY_CHANGED },

    WIDGET_INHERIT_OPTIONS(TabOptionSpecs)
};

/*------------------------------------------------------------------------
 * +++ Notebook resources.
 */
typedef struct
{
    Tcl_Obj *widthObj;		/* Default width */
    Tcl_Obj *heightObj;		/* Default height */
    Tcl_Obj *paddingObj;	/* Padding around notebook */

    Ttk_Manager *mgr;		/* Geometry manager */
    Tk_OptionTable tabOptionTable;	/* Tab options */
    Tk_OptionTable paneOptionTable;	/* Tab+pane options */
    TkSizeT currentIndex;		/* index of currently selected tab */
    TkSizeT activeIndex;		/* index of currently active tab */
    Ttk_Layout tabLayout;	/* Sublayout for tabs */

    Ttk_Box clientArea;		/* Where to pack slave widgets */
    Ttk_Box clientArea;		/* Where to pack content windows */
} NotebookPart;

typedef struct
{
    WidgetCore core;
    NotebookPart notebook;
} Notebook;
183
184
185
186
187
188
189
190

191
192
193
194
195
196

197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212

213
214
215
216
217
218
219
220
221

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

234
235
236
237
238
239
240
183
184
185
186
187
188
189

190
191
192
193
194
195

196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211

212
213
214
215
216
217
218
219
220

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

233
234
235
236
237
238
239
240







-
+





-
+















-
+








-
+











-
+







    }
}

/*------------------------------------------------------------------------
 * +++ Tab management.
 */

static Tab *CreateTab(Tcl_Interp *interp, Notebook *nb, Tk_Window slaveWindow)
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, slaveWindow) != TCL_OK) {
    if (Tk_InitOptions(interp, record, optionTable, window) != TCL_OK) {
	ckfree(record);
	return NULL;
    }

    return record;
}

static void DestroyTab(Notebook *nb, Tab *tab)
{
    void *record = tab;
    Tk_FreeConfigOptions(record, nb->notebook.paneOptionTable, nb->core.tkwin);
    ckfree(record);
}

static int ConfigureTab(
    Tcl_Interp *interp, Notebook *nb, Tab *tab, Tk_Window slaveWindow,
    Tcl_Interp *interp, Notebook *nb, Tab *tab, Tk_Window window,
    int objc, Tcl_Obj *const objv[])
{
    Ttk_Sticky sticky = tab->sticky;
    Ttk_Padding padding = tab->padding;
    Tk_SavedOptions savedOptions;
    int mask = 0;

    if (Tk_SetOptions(interp, tab, nb->notebook.paneOptionTable,
	    objc, objv, slaveWindow, &savedOptions, &mask) != TCL_OK)
	    objc, objv, window, &savedOptions, &mask) != TCL_OK)
    {
	return TCL_ERROR;
    }

    /* Check options:
     * @@@ TODO: validate -image option.
     */
    if (Ttk_GetStickyFromObj(interp, tab->stickyObj, &sticky) != TCL_OK)
    {
	goto error;
    }
    if (Ttk_GetPaddingFromObj(interp, slaveWindow, tab->paddingObj, &padding)
    if (Ttk_GetPaddingFromObj(interp, window, tab->paddingObj, &padding)
	    != TCL_OK)
    {
	goto error;
    }

    tab->sticky = sticky;
    tab->padding = padding;
253
254
255
256
257
258
259
260
261


262
263
264
265
266
267
268
253
254
255
256
257
258
259


260
261
262
263
264
265
266
267
268







-
-
+
+







 * IdentifyTab --
 * 	Return the index of the tab at point x,y,
 * 	or -1 if no tab at that point.
 */
static TkSizeT IdentifyTab(Notebook *nb, int x, int y)
{
    TkSizeT index;
    for (index = 0; index < Ttk_NumberSlaves(nb->notebook.mgr); ++index) {
	Tab *tab = (Tab *)Ttk_SlaveData(nb->notebook.mgr,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;
286
287
288
289
290
291
292
293

294
295
296
297
298
299
300
301
302
303
304
305
306


307
308
309
310
311
312
313
314
315
316


317
318
319
320
321
322
323
324
325

326
327
328
329
330
331
332
286
287
288
289
290
291
292

293
294
295
296
297
298
299
300
301
302
303
304


305
306
307
308
309
310
311
312
313
314


315
316
317
318
319
320
321
322
323
324

325
326
327
328
329
330
331
332







-
+











-
-
+
+








-
-
+
+








-
+







 * 	notebook state, currentIndex, activeIndex, and user-specified tab state.
 *	The USER1 bit is set for the leftmost visible tab, and USER2
 * 	is set for the rightmost visible tab.
 */
static Ttk_State TabState(Notebook *nb, TkSizeT index)
{
    Ttk_State state = nb->core.state;
    Tab *tab = (Tab *)Ttk_SlaveData(nb->notebook.mgr, index);
    Tab *itab = (Tab *)Ttk_ContentData(nb->notebook.mgr, index);
    TkSizeT i = 0;

    if (index == nb->notebook.currentIndex) {
	state |= TTK_STATE_SELECTED;
    } else {
	state &= ~TTK_STATE_FOCUS;
    }

    if (index == nb->notebook.activeIndex) {
	state |= TTK_STATE_ACTIVE;
    }
    for (i = 0; i < Ttk_NumberSlaves(nb->notebook.mgr); ++i) {
	Tab *tab = (Tab *)Ttk_SlaveData(nb->notebook.mgr, i);
    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_NumberSlaves(nb->notebook.mgr) - 1; i != TCL_INDEX_NONE; --i) {
	Tab *tab = (Tab *)Ttk_SlaveData(nb->notebook.mgr, i);
    for (i = Ttk_NumberContent(nb->notebook.mgr) - 1; i != TCL_INDEX_NONE; --i) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, i);
	if (tab->state == TAB_STATE_HIDDEN) {
	    continue;
	}
	if (index == i) {
	    state |= TTK_STATE_USER2;
	}
	break;
    }
    if (tab->state == TAB_STATE_DISABLED) {
    if (itab->state == TAB_STATE_DISABLED) {
	state |= TTK_STATE_DISABLED;
    }

    return state;
}

/*------------------------------------------------------------------------
349
350
351
352
353
354
355
356
357


358
359
360
361
362
363
364
349
350
351
352
353
354
355


356
357
358
359
360
361
362
363
364







-
-
+
+







static void TabrowSize(
    Notebook *nb, Ttk_Orient orient, int minTabWidth, int *widthPtr, int *heightPtr)
{
    Ttk_Layout tabLayout = nb->notebook.tabLayout;
    int tabrowWidth = 0, tabrowHeight = 0;
    TkSizeT i;

    for (i = 0; i < Ttk_NumberSlaves(nb->notebook.mgr); ++i) {
	Tab *tab = (Tab *)Ttk_SlaveData(nb->notebook.mgr, i);
    for (i = 0; i < Ttk_NumberContent(nb->notebook.mgr); ++i) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, i);
	Ttk_State tabState = TabState(nb,i);

	Ttk_RebindSublayout(tabLayout, tab);
	Ttk_LayoutSize(tabLayout,tabState,&tab->width,&tab->height);
        tab->width = MAX(tab->width, minTabWidth);

	if (orient == TTK_ORIENT_HORIZONTAL) {
374
375
376
377
378
379
380
381

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

399
400
401
402
403
404
405
406







407
408
409


410
411
412
413
414
415
416
374
375
376
377
378
379
380

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

398
399







400
401
402
403
404
405
406
407


408
409
410
411
412
413
414
415
416







-
+
















-
+

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

-
-
+
+







    *heightPtr = tabrowHeight;
}

/* NotebookSize -- GM and widget size hook.
 *
 * Total height is tab height + client area height + pane internal padding
 * Total width is max(client width, tab width) + pane internal padding
 * Client area size determined by max size of slaves,
 * 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;
    NotebookStyle nbstyle;
    Ttk_Padding padding;
    Ttk_Element clientNode = Ttk_FindElement(nb->core.layout, "client");
    int clientWidth = 0, clientHeight = 0,
    	reqWidth = 0, reqHeight = 0,
	tabrowWidth = 0, tabrowHeight = 0;
    TkSizeT i;

    NotebookStyleOptions(nb, &nbstyle);

    /* Compute max requested size of all slaves:
    /* Compute max requested size of all content windows:
     */
    for (i = 0; i < Ttk_NumberSlaves(nb->notebook.mgr); ++i) {
	Tk_Window slaveWindow = Ttk_SlaveWindow(nb->notebook.mgr, i);
	Tab *tab = (Tab *)Ttk_SlaveData(nb->notebook.mgr, i);
	int slaveWidth
	    = Tk_ReqWidth(slaveWindow) + Ttk_PaddingWidth(tab->padding);
	int slaveHeight
	    = Tk_ReqHeight(slaveWindow) + Ttk_PaddingHeight(tab->padding);
    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, slaveWidth);
	clientHeight = MAX(clientHeight, slaveHeight);
	clientWidth = MAX(clientWidth, width);
	clientHeight = MAX(clientHeight, height);
    }

    /* Client width/height overridable by widget options:
     */
    Tcl_GetIntFromObj(NULL, nb->notebook.widthObj,&reqWidth);
    Tcl_GetIntFromObj(NULL, nb->notebook.heightObj,&reqHeight);
    if (reqWidth > 0)
457
458
459
460
461
462
463
464

465
466
467
468
469
470
471
472
473

474
475
476
477
478
479
480
481
482
483
484
485
486
487
488

489
490
491
492

493
494
495
496
497
498
499
457
458
459
460
461
462
463

464
465
466
467
468
469
470
471
472

473
474
475
476
477
478
479
480
481
482
483
484
485
486
487

488
489
490
491

492
493
494
495
496
497
498
499







-
+








-
+














-
+



-
+







 * @@@ <<NOTE-TABPOSITION>> bug: only works for horizontal orientations
 * @@@ <<NOTE-SQUEEZE-HIDDEN>> does not account for hidden tabs.
 */

static void SqueezeTabs(
    Notebook *nb, int needed, int available)
{
    int nTabs = Ttk_NumberSlaves(nb->notebook.mgr);
    int nTabs = Ttk_NumberContent(nb->notebook.mgr);

    if (nTabs > 0) {
	int difference = available - needed;
	double delta = (double)difference / needed;
	double slack = 0;
	int i;

	for (i = 0; i < nTabs; ++i) {
	    Tab *tab = (Tab *)Ttk_SlaveData(nb->notebook.mgr,i);
	    Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr,i);
	    double ad = slack + tab->width * delta;
	    tab->width += (int)ad;
	    slack = ad - (int)ad;
	}
    }
}

/* PlaceTabs --
 * 	Compute all tab parcels.
 */
static void PlaceTabs(
    Notebook *nb, Ttk_Box tabrowBox, Ttk_PositionSpec tabPlacement)
{
    Ttk_Layout tabLayout = nb->notebook.tabLayout;
    int nTabs = Ttk_NumberSlaves(nb->notebook.mgr);
    int nTabs = Ttk_NumberContent(nb->notebook.mgr);
    int i;

    for (i = 0; i < nTabs; ++i) {
	Tab *tab = (Tab *)Ttk_SlaveData(nb->notebook.mgr, i);
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, i);
	Ttk_State tabState = TabState(nb, i);

	if (tab->state != TAB_STATE_HIDDEN) {
	    Ttk_Padding expand = Ttk_UniformPadding(0);
	    Tcl_Obj *expandObj = Ttk_QueryOption(tabLayout,"-expand",tabState);

	    if (expandObj) {
509
510
511
512
513
514
515
516

517
518
519
520
521
522
523
509
510
511
512
513
514
515

516
517
518
519
520
521
522
523







-
+







    }
}

/* NotebookDoLayout --
 *	Computes notebook layout and places tabs.
 *
 * Side effects:
 * 	Sets clientArea, used to place slave panes.
 * 	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;
563
564
565
566
567
568
569
570

571
572

573
574

575
576
577
578



579
580

581
582
583


584
585
586

587
588
589

590
591
592
593
594
595

596
597
598
599
600
601
602
603
604
605

606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623

624
625
626
627


628
629
630
631

632
633
634

635
636
637
638
639
640
641
642
643
644

645
646
647
648
649
650

651
652
653
654
655
656
657
658
659

660
661
662
663
664
665
666
563
564
565
566
567
568
569

570
571

572
573

574
575



576
577
578
579

580
581


582
583
584
585

586
587
588

589
590
591
592
593
594

595
596
597
598
599
600
601
602
603
604

605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622

623
624
625


626
627
628
629
630

631
632
633

634
635
636
637
638
639
640
641
642
643

644
645
646
647
648
649

650
651
652
653
654
655
656
657
658

659
660
661
662
663
664
665
666







-
+

-
+

-
+

-
-
-
+
+
+

-
+

-
-
+
+


-
+


-
+





-
+









-
+

















-
+


-
-
+
+



-
+


-
+









-
+





-
+








-
+







    if (cavity.height <= 0) cavity.height = 1;
    if (cavity.width <= 0) cavity.width = 1;

    nb->notebook.clientArea = cavity;
}

/*
 * NotebookPlaceSlave --
 * NotebookPlaceContent --
 * 	Set the position and size of a child widget
 * 	based on the current client area and slave options:
 * 	based on the current client area and content window options:
 */
static void NotebookPlaceSlave(Notebook *nb, TkSizeT slaveIndex)
static void NotebookPlaceContent(Notebook *nb, TkSizeT index)
{
    Tab *tab = (Tab *)Ttk_SlaveData(nb->notebook.mgr, slaveIndex);
    Tk_Window slaveWindow = Ttk_SlaveWindow(nb->notebook.mgr, slaveIndex);
    Ttk_Box slaveBox =
    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(slaveWindow), Tk_ReqHeight(slaveWindow),tab->sticky);
	    Tk_ReqWidth(window), Tk_ReqHeight(window),tab->sticky);

    Ttk_PlaceSlave(nb->notebook.mgr, slaveIndex,
	slaveBox.x, slaveBox.y, slaveBox.width, slaveBox.height);
    Ttk_PlaceContent(nb->notebook.mgr, index,
	box.x, box.y, box.width, box.height);
}

/* NotebookPlaceSlaves --
/* NotebookPlaceContents --
 * 	Geometry manager hook.
 */
static void NotebookPlaceSlaves(void *recordPtr)
static void NotebookPlaceContents(void *recordPtr)
{
    Notebook *nb = (Notebook *)recordPtr;
    TkSizeT currentIndex = nb->notebook.currentIndex;
    if (currentIndex != TCL_INDEX_NONE) {
	NotebookDoLayout(nb);
	NotebookPlaceSlave(nb, currentIndex);
	NotebookPlaceContent(nb, currentIndex);
    }
}

/*
 * SelectTab(nb, index) --
 * 	Change the currently-selected tab.
 */
static void SelectTab(Notebook *nb, TkSizeT index)
{
    Tab *tab = (Tab *)Ttk_SlaveData(nb->notebook.mgr, index);
    Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, index);
    TkSizeT currentIndex = nb->notebook.currentIndex;

    if (index == currentIndex) {
	return;
    }

    if (TabState(nb, index) & TTK_STATE_DISABLED) {
	return;
    }

    /* Unhide the tab if it is currently hidden and being selected.
     */
    if (tab->state == TAB_STATE_HIDDEN) {
	tab->state = TAB_STATE_NORMAL;
    }

    if (currentIndex != TCL_INDEX_NONE) {
	Ttk_UnmapSlave(nb->notebook.mgr, currentIndex);
	Ttk_UnmapContent(nb->notebook.mgr, currentIndex);
    }

    /* Must be set before calling NotebookPlaceSlave(), otherwise it may
     * happen that NotebookPlaceSlaves(), triggered by an interveaning
    /* 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;

    NotebookPlaceSlave(nb, index);
    NotebookPlaceContent(nb, index);
    TtkRedisplayWidget(&nb->core);

    TtkSendVirtualEvent(nb->core.tkwin, "NotebookTabChanged");
    Tk_SendVirtualEvent(nb->core.tkwin, "NotebookTabChanged", NULL);
}

/* NextTab --
 * 	Returns the index of the next tab after the specified tab
 * 	in the normal state (e.g., not hidden or disabled),
 * 	or -1 if all tabs are disabled or hidden.
 */
static int NextTab(Notebook *nb, int index)
{
    TkSizeT nTabs = Ttk_NumberSlaves(nb->notebook.mgr);
    TkSizeT nTabs = Ttk_NumberContent(nb->notebook.mgr);
    TkSizeT nextIndex;

    /* Scan forward for following usable tab:
     */
    for (nextIndex = index + 1; nextIndex + 1 < nTabs + 1; ++nextIndex) {
	Tab *tab = (Tab *)Ttk_SlaveData(nb->notebook.mgr, nextIndex);
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, nextIndex);
	if (tab->state == TAB_STATE_NORMAL) {
	    return nextIndex;
	}
    }

    /* Not found -- scan backwards.
     */
    for (nextIndex = index - 1; nextIndex != TCL_INDEX_NONE; --nextIndex) {
	Tab *tab = (Tab *)Ttk_SlaveData(nb->notebook.mgr, nextIndex);
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, nextIndex);
	if (tab->state == TAB_STATE_NORMAL) {
	    return nextIndex;
	}
    }

    /* Still nothing.  Give up.
     */
676
677
678
679
680
681
682
683

684
685
686

687
688
689
690
691
692
693
694

695
696

697
698
699
700
701

702
703
704
705
706
707
708
709
710
711
712
713
714
715
716

717
718
719
720




721
722

723
724
725
726
727
728
729
730
731

732
733
734
735

736
737
738
739

740
741

742
743
744
745
746
747
748
749

750
751
752
753

754
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
676
677
678
679
680
681
682

683
684
685

686
687
688
689
690
691
692
693

694
695

696
697
698
699
700

701
702
703
704
705
706
707
708
709
710
711
712
713
714
715

716




717
718
719
720


721
722
723
724
725
726
727
728
729

730
731
732
733

734
735
736
737

738
739

740
741
742
743
744
745
746
747

748
749
750
751

752
753
754
755
756

757
758
759
760
761
762
763
764
765
766
767
768
769
770

771
772

773
774
775
776
777
778
779
780







-
+


-
+







-
+

-
+




-
+














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








-
+



-
+



-
+

-
+







-
+



-
+




-
+













-
+

-
+







 */
static void SelectNearestTab(Notebook *nb)
{
    TkSizeT currentIndex = nb->notebook.currentIndex;
    TkSizeT nextIndex = NextTab(nb, currentIndex);

    if (currentIndex != TCL_INDEX_NONE) {
	Ttk_UnmapSlave(nb->notebook.mgr, currentIndex);
	Ttk_UnmapContent(nb->notebook.mgr, currentIndex);
    }
    if (currentIndex != nextIndex) {
	TtkSendVirtualEvent(nb->core.tkwin, "NotebookTabChanged");
	Tk_SendVirtualEvent(nb->core.tkwin, "NotebookTabChanged", NULL);
    }

    nb->notebook.currentIndex = nextIndex;
    Ttk_ManagerLayoutChanged(nb->notebook.mgr);
    TtkRedisplayWidget(&nb->core);
}

/* TabRemoved -- GM SlaveRemoved hook.
/* TabRemoved -- GM TabRemoved hook.
 * 	Select the next tab if the current one is being removed.
 * 	Adjust currentIndex to account for removed slave.
 * 	Adjust currentIndex to account for removed content window.
 */
static void TabRemoved(void *managerData, TkSizeT index)
{
    Notebook *nb = (Notebook *)managerData;
    Tab *tab = (Tab *)Ttk_SlaveData(nb->notebook.mgr, index);
    Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, index);

    if (index == nb->notebook.currentIndex) {
	SelectNearestTab(nb);
    }

    if (index + 1 < nb->notebook.currentIndex + 1) {
	--nb->notebook.currentIndex;
    }

    DestroyTab(nb, tab);

    TtkRedisplayWidget(&nb->core);
}

static int TabRequest(void *managerData, TkSizeT index, int width, int height)
static int TabRequest(
{
    (void)managerData;
    (void)index;
    (void)width;
    TCL_UNUSED(void *),
    TCL_UNUSED(TkSizeT),
    TCL_UNUSED(int),
    TCL_UNUSED(int))
    (void)height;

{
    return 1;
}

/* AddTab --
 * 	Add new tab at specified index.
 */
static int AddTab(
    Tcl_Interp *interp, Notebook *nb,
    TkSizeT destIndex, Tk_Window slaveWindow,
    TkSizeT destIndex, Tk_Window window,
    int objc, Tcl_Obj *const objv[])
{
    Tab *tab;
    if (!Ttk_Maintainable(interp, slaveWindow, nb->core.tkwin)) {
    if (!Ttk_Maintainable(interp, window, nb->core.tkwin)) {
	return TCL_ERROR;
    }
#if 0 /* can't happen */
    if (Ttk_SlaveIndex(nb->notebook.mgr, slaveWindow) != TCL_INDEX_NONE) {
    if (Ttk_ContentIndex(nb->notebook.mgr, window) != TCL_INDEX_NONE) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("%s already added",
	    Tk_PathName(slaveWindow)));
	    Tk_PathName(window)));
	Tcl_SetErrorCode(interp, "TTK", "NOTEBOOK", "PRESENT", NULL);
	return TCL_ERROR;
    }
#endif

    /* Create and insert tab.
     */
    tab = CreateTab(interp, nb, slaveWindow);
    tab = CreateTab(interp, nb, window);
    if (!tab) {
	return TCL_ERROR;
    }
    if (ConfigureTab(interp, nb, tab, slaveWindow, objc, objv) != TCL_OK) {
    if (ConfigureTab(interp, nb, tab, window, objc, objv) != TCL_OK) {
	DestroyTab(nb, tab);
	return TCL_ERROR;
    }

    Ttk_InsertSlave(nb->notebook.mgr, destIndex, slaveWindow, tab);
    Ttk_InsertContent(nb->notebook.mgr, destIndex, window, tab);

    /* Adjust indices and/or autoselect first tab:
     */
    if (nb->notebook.currentIndex == TCL_INDEX_NONE) {
	SelectTab(nb, destIndex);
    } else if (nb->notebook.currentIndex + 1 >= destIndex + 1) {
	++nb->notebook.currentIndex;
    }

    return TCL_OK;
}

static Ttk_ManagerSpec NotebookManagerSpec = {
    { "notebook", Ttk_GeometryRequestProc, Ttk_LostSlaveProc },
    { "notebook", Ttk_GeometryRequestProc, Ttk_LostContentProc },
    NotebookSize,
    NotebookPlaceSlaves,
    NotebookPlaceContents,
    TabRequest,
    TabRemoved
};

/*------------------------------------------------------------------------
 * +++ Event handlers.
 */
810
811
812
813
814
815
816
817

818
819
820
821
822
823
824
809
810
811
812
813
814
815

816
817
818
819
820
821
822
823







-
+







/* FindTabIndex --
 *	Find the index of the specified tab.
 *	Tab identifiers are one of:
 *
 *	+ positional specifications @x,y,
 *	+ "current",
 *	+ numeric indices [0..nTabs],
 *	+ slave window names
 *	+ content window names
 *
 *	Stores index of specified tab in *index_rtn, -1 if not found.
 *
 *	Returns TCL_ERROR and leaves an error message in interp->result
 *	if the tab identifier was incorrect.
 *
 *	See also: GetTabIndex.
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
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







-
+

-
+




-
+

-
-
+
+



-
+













-
+

-
-
+
+







    /* ... or "current" ...
     */
    if (!strcmp(string, "current")) {
	*index_rtn = nb->notebook.currentIndex;
	return TCL_OK;
    }

    /* ... or integer index or slave window name:
    /* ... or integer index or content window name:
     */
    if (Ttk_GetSlaveIndexFromObj(
    if (Ttk_GetContentIndexFromObj(
	    interp, nb->notebook.mgr, objPtr, index_rtn) == TCL_OK)
    {
	return TCL_OK;
    }
    if (*index_rtn == Ttk_NumberSlaves(nb->notebook.mgr)) {
    if (*index_rtn == Ttk_NumberContent(nb->notebook.mgr)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"Invalid slave specification %s", string));
	Tcl_SetErrorCode(interp, "TTK", "SLAVE", "SPEC", NULL);
		"Invalid tab specification %s", string));
	Tcl_SetErrorCode(interp, "TTK", "NOTEBOOK", "SPEC", NULL);
	return TCL_ERROR;
    }

    /* Nothing matched; Ttk_GetSlaveIndexFromObj will have left error message.
    /* Nothing matched; Ttk_GetContentIndexFromObj will have left error message.
     */
    return TCL_ERROR;
}

/* GetTabIndex --
 * 	Get the index of an existing tab.
 * 	Tab identifiers are as per FindTabIndex.
 * 	Returns TCL_ERROR if the tab does not exist.
 */
static int GetTabIndex(
    Tcl_Interp *interp, Notebook *nb, Tcl_Obj *objPtr, TkSizeT *index_rtn)
{
    int status = FindTabIndex(interp, nb, objPtr, index_rtn);
	if (status == TCL_OK && *index_rtn + 1 >= Ttk_NumberSlaves(nb->notebook.mgr) + 1) {
	if (status == TCL_OK && *index_rtn + 1 >= Ttk_NumberContent(nb->notebook.mgr) + 1) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"Slave index %s out of bounds", Tcl_GetString(objPtr)));
	    Tcl_SetErrorCode(interp, "TTK", "SLAVE", "INDEX", NULL);
		"tab index %s out of bounds", Tcl_GetString(objPtr)));
	    Tcl_SetErrorCode(interp, "TTK", "NOTEBOOK", "INDEX", NULL);
	    return TCL_ERROR;
	}

    if (status == TCL_OK && *index_rtn == TCL_INDEX_NONE) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "tab '%s' not found", Tcl_GetString(objPtr)));
	Tcl_SetErrorCode(interp, "TTK", "NOTEBOOK", "TAB", NULL);
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
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







-
-
-
+
+







-
-
+
+


-
+

-
-
+
+


-
+



-
+
















-
+



-
+



-
+





-
+

-
+


-
+



-
-
-
+
+
+

-
+



-
-
+
+


-
+


-
-
+
+





-
-
+
+

-
+








/* $nb add window ?options ... ?
 */
static int NotebookAddCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Notebook *nb = (Notebook *)recordPtr;
    int index = Ttk_NumberSlaves(nb->notebook.mgr);
    Tk_Window slaveWindow;
    int slaveIndex;
    Tk_Window window;
    int index;
    Tab *tab;

    if (objc <= 2 || objc % 2 != 1) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?-option value ...?");
	return TCL_ERROR;
    }

    slaveWindow = Tk_NameToWindow(interp,Tcl_GetString(objv[2]),nb->core.tkwin);
    if (!slaveWindow) {
    window = Tk_NameToWindow(interp,Tcl_GetString(objv[2]),nb->core.tkwin);
    if (!window) {
	return TCL_ERROR;
    }
    slaveIndex = Ttk_SlaveIndex(nb->notebook.mgr, slaveWindow);
    index = Ttk_ContentIndex(nb->notebook.mgr, window);

    if (slaveIndex < 0) { /* New tab */
	return AddTab(interp, nb, index, slaveWindow, objc-3,objv+3);
    if (index < 0) { /* New tab */
	return AddTab(interp, nb, Ttk_NumberContent(nb->notebook.mgr), window, objc-3,objv+3);
    }

    tab = (Tab *)Ttk_SlaveData(nb->notebook.mgr, slaveIndex);
    tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, index);
    if (tab->state == TAB_STATE_HIDDEN) {
	tab->state = TAB_STATE_NORMAL;
    }
    if (ConfigureTab(interp, nb, tab, slaveWindow, objc-3,objv+3) != TCL_OK) {
    if (ConfigureTab(interp, nb, tab, window, objc-3,objv+3) != TCL_OK) {
	return TCL_ERROR;
    }

    TtkRedisplayWidget(&nb->core);

    return TCL_OK;
}

/* $nb insert $index $tab ?-option value ...?
 * 	Insert new tab, or move existing one.
 */
static int NotebookInsertCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Notebook *nb = (Notebook *)recordPtr;
    TkSizeT current = nb->notebook.currentIndex;
    TkSizeT nSlaves = Ttk_NumberSlaves(nb->notebook.mgr);
    TkSizeT nContent = Ttk_NumberContent(nb->notebook.mgr);
    TkSizeT srcIndex, destIndex;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2,objv, "index slave ?-option value ...?");
	Tcl_WrongNumArgs(interp, 2,objv, "index window ?-option value ...?");
	return TCL_ERROR;
    }

    if (TCL_OK != Ttk_GetSlaveIndexFromObj(
    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 slave.
	/* Window name -- could be new or existing content window.
	 */
	Tk_Window slaveWindow =
	Tk_Window window =
	    Tk_NameToWindow(interp,Tcl_GetString(objv[3]),nb->core.tkwin);

	if (!slaveWindow) {
	if (!window) {
	    return TCL_ERROR;
	}

	srcIndex = Ttk_SlaveIndex(nb->notebook.mgr, slaveWindow);
	if (srcIndex == TCL_INDEX_NONE) {	/* New slave */
	    return AddTab(interp, nb, destIndex, slaveWindow, objc-4,objv+4);
	srcIndex = Ttk_ContentIndex(nb->notebook.mgr, window);
	if (srcIndex == TCL_INDEX_NONE) {	/* New content window */
	    return AddTab(interp, nb, destIndex, window, objc-4,objv+4);
	}
    } else if (Ttk_GetSlaveIndexFromObj(
    } else if (Ttk_GetContentIndexFromObj(
		interp, nb->notebook.mgr, objv[3], &srcIndex) != TCL_OK)
    {
	return TCL_ERROR;
    } else if (srcIndex + 1 >= Ttk_NumberSlaves(nb->notebook.mgr) + 1) {
	srcIndex = Ttk_NumberSlaves(nb->notebook.mgr) - 1;
    } else if (srcIndex + 1 >= Ttk_NumberContent(nb->notebook.mgr) + 1) {
	srcIndex = Ttk_NumberContent(nb->notebook.mgr) - 1;
    }

    /* Move existing slave:
    /* Move existing content window:
     */
    if (ConfigureTab(interp, nb,
	     (Tab *)Ttk_SlaveData(nb->notebook.mgr, srcIndex),
	     Ttk_SlaveWindow(nb->notebook.mgr, srcIndex),
	     (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 >= nSlaves + 1) {
	destIndex  = nSlaves - 1;
    if (destIndex + 1 >= nContent + 1) {
	destIndex  = nContent - 1;
    }
    Ttk_ReorderSlave(nb->notebook.mgr, srcIndex, destIndex);
    Ttk_ReorderContent(nb->notebook.mgr, srcIndex, destIndex);

    /* Adjust internal indexes:
     */
    nb->notebook.activeIndex = TCL_INDEX_NONE;
    if (current == srcIndex) {
	nb->notebook.currentIndex = destIndex;
    } else if (destIndex + 1 <= current + 1 && current + 1 < srcIndex + 1) {
1020
1021
1022
1023
1024
1025
1026
1027

1028
1029
1030
1031
1032
1033
1034
1018
1019
1020
1021
1022
1023
1024

1025
1026
1027
1028
1029
1030
1031
1032







-
+







	return TCL_ERROR;
    }

    if (GetTabIndex(interp, nb, objv[2], &index) != TCL_OK) {
	return TCL_ERROR;
    }

    Ttk_ForgetSlave(nb->notebook.mgr, index);
    Ttk_ForgetContent(nb->notebook.mgr, index);
    TtkRedisplayWidget(&nb->core);

    return TCL_OK;
}

/* $nb hide $tab --
 * 	Hides the specified tab.
1045
1046
1047
1048
1049
1050
1051
1052

1053
1054
1055
1056
1057
1058
1059
1043
1044
1045
1046
1047
1048
1049

1050
1051
1052
1053
1054
1055
1056
1057







-
+







	return TCL_ERROR;
    }

    if (GetTabIndex(interp, nb, objv[2], &index) != TCL_OK) {
	return TCL_ERROR;
    }

    tab = (Tab *)Ttk_SlaveData(nb->notebook.mgr, index);
    tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, index);
    tab->state = TAB_STATE_HIDDEN;
    if (index == nb->notebook.currentIndex) {
	SelectNearestTab(nb);
    }

    TtkRedisplayWidget(&nb->core);

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







-
+









-
+


















-
-
+
+
-







    TkSizeT tabIndex;

    if (objc < 4 || objc > 5) {
	Tcl_WrongNumArgs(interp, 2,objv, "?what? x y");
	return TCL_ERROR;
    }

    if (   Tcl_GetIntFromObj(interp, objv[objc-2], &x) != TCL_OK
    if (Tcl_GetIntFromObj(interp, objv[objc-2], &x) != TCL_OK
	|| Tcl_GetIntFromObj(interp, objv[objc-1], &y) != TCL_OK
	|| (objc == 5 && Tcl_GetIndexFromObjStruct(interp, objv[2], whatTable,
		sizeof(char *), "option", 0, &what) != TCL_OK)
    ) {
	return TCL_ERROR;
    }

    tabIndex = IdentifyTab(nb, x, y);
    if (tabIndex != TCL_INDEX_NONE) {
	Tab *tab = (Tab *)Ttk_SlaveData(nb->notebook.mgr, tabIndex);
	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, Tcl_NewWideIntObj(tabIndex));
	    if (tabIndex != TCL_INDEX_NONE)
	    Tcl_SetObjResult(interp, TkNewIndexObj(tabIndex));
	    }
	    break;
    }
    return TCL_OK;
}

/* $nb index $item --
 * 	Returns the integer index of the tab specified by $item,
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
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







-
-
+
+
+
















-
+








    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "tab");
	return TCL_ERROR;
    }

    status = FindTabIndex(interp, nb, objv[2], &index);
    if (status == TCL_OK && index != TCL_INDEX_NONE) {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index));
	if (status == TCL_OK) {
	if (index != TCL_INDEX_NONE)
	Tcl_SetObjResult(interp, TkNewIndexObj(index));
    }

    return status;
}

/* $nb select ?$item? --
 * 	Select the specified tab, or return the widget path of
 * 	the currently-selected pane.
 */
static int NotebookSelectCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Notebook *nb = (Notebook *)recordPtr;

    if (objc == 2) {
	if (nb->notebook.currentIndex != TCL_INDEX_NONE) {
	    Tk_Window pane = Ttk_SlaveWindow(
	    Tk_Window pane = Ttk_ContentWindow(
		nb->notebook.mgr, nb->notebook.currentIndex);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(pane), -1));
	}
	return TCL_OK;
    } else if (objc == 3) {
	TkSizeT index;
	int status = GetTabIndex(interp, nb, objv[2], &index);
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
1180
1181
1182
1183
1184
1185
1186


1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203

1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215


1216
1217
1218
1219
1220

1221
1222
1223

1224
1225
1226

1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244

1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262







-
-
+
+















-
+











-
-
+
+



-
+


-
+


-
+

















-

+








+








    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, "");
	return TCL_ERROR;
    }

    result = Tcl_NewListObj(0, NULL);
    for (i = 0; i < Ttk_NumberSlaves(mgr); ++i) {
	const char *pathName = Tk_PathName(Ttk_SlaveWindow(mgr,i));
    for (i = 0; i < Ttk_NumberContent(mgr); ++i) {
	const char *pathName = Tk_PathName(Ttk_ContentWindow(mgr,i));

	Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj(pathName,-1));
    }
    Tcl_SetObjResult(interp, result);
    return TCL_OK;
}

/* $nb tab $tab ?-option ?value -option value...??
 */
static int NotebookTabCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Notebook *nb = (Notebook *)recordPtr;
    Ttk_Manager *mgr = nb->notebook.mgr;
    TkSizeT index;
    Tk_Window slaveWindow;
    Tk_Window window;
    Tab *tab;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "tab ?-option ?value??...");
	return TCL_ERROR;
    }

    if (GetTabIndex(interp, nb, objv[2], &index) != TCL_OK) {
	return TCL_ERROR;
    }

    tab = (Tab *)Ttk_SlaveData(mgr, index);
    slaveWindow = Ttk_SlaveWindow(mgr, index);
    tab = (Tab *)Ttk_ContentData(mgr, index);
    window = Ttk_ContentWindow(mgr, index);

    if (objc == 3) {
	return TtkEnumerateOptions(interp, tab,
	    PaneOptionSpecs, nb->notebook.paneOptionTable, slaveWindow);
	    PaneOptionSpecs, nb->notebook.paneOptionTable, window);
    } else if (objc == 4) {
	return TtkGetOptionValue(interp, tab, objv[3],
	    nb->notebook.paneOptionTable, slaveWindow);
	    nb->notebook.paneOptionTable, window);
    } /* else */

    if (ConfigureTab(interp, nb, tab, slaveWindow, objc-3,objv+3) != TCL_OK) {
    if (ConfigureTab(interp, nb, tab, window, objc-3,objv+3) != TCL_OK) {
	return TCL_ERROR;
    }

    /* If the current tab has become disabled or hidden,
     * select the next nondisabled, unhidden one:
     */
    if (index == nb->notebook.currentIndex && tab->state != TAB_STATE_NORMAL) {
	SelectNearestTab(nb);
    }

    return TCL_OK;
}

/* Subcommand table:
 */
static const Ttk_Ensemble NotebookCommands[] = {
    { "add",    	NotebookAddCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "forget",		NotebookForgetCommand,0 },
    { "hide",		NotebookHideCommand,0 },
    { "identify",	NotebookIdentifyCommand,0 },
    { "index",		NotebookIndexCommand,0 },
    { "insert",  	NotebookInsertCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "select",		NotebookSelectCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    { "tab",   		NotebookTabCommand,0 },
    { "tabs",   	NotebookTabsCommand,0 },
    { 0,0,0 }
};

/*------------------------------------------------------------------------
 * +++ Widget class hooks.
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
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







-
+












-
+









-
+







/*------------------------------------------------------------------------
 * +++ Display routines.
 */

static void DisplayTab(Notebook *nb, int index, Drawable d)
{
    Ttk_Layout tabLayout = nb->notebook.tabLayout;
    Tab *tab = (Tab *)Ttk_SlaveData(nb->notebook.mgr, index);
    Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, index);
    Ttk_State state = TabState(nb, index);

    if (tab->state != TAB_STATE_HIDDEN) {
	Ttk_RebindSublayout(tabLayout, tab);
	Ttk_PlaceLayout(tabLayout, state, tab->parcel);
	Ttk_DrawLayout(tabLayout, state, d);
    }
}

static void NotebookDisplay(void *clientData, Drawable d)
{
    Notebook *nb = (Notebook *)clientData;
    TkSizeT nSlaves = Ttk_NumberSlaves(nb->notebook.mgr);
    TkSizeT nContent = Ttk_NumberContent(nb->notebook.mgr);
    TkSizeT index;

    /* Draw notebook background (base layout):
     */
    Ttk_DrawLayout(nb->core.layout, nb->core.state, d);

    /* Draw tabs from left to right, but draw the current tab last
     * so it will overwrite its neighbors.
     */
    for (index = 0; index < nSlaves; ++index) {
    for (index = 0; index < nContent; ++index) {
	if (index != nb->notebook.currentIndex) {
	    DisplayTab(nb, index, d);
	}
    }
    if (nb->notebook.currentIndex != TCL_INDEX_NONE) {
	DisplayTab(nb, nb->notebook.currentIndex, d);
    }

Changes to generic/ttk/ttkPanedwindow.c.

1
2

3
4
5
6
7
8
9
1

2
3
4
5
6
7
8
9

-
+







/*
 * Copyright (c) 2005, Joe English.  Freely redistributable.
 * Copyright © 2005 Joe English.  Freely redistributable.
 *
 * ttk::panedwindow widget implementation.
 *
 * TODO: track active/pressed sash.
 */

#include "tkInt.h"
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







-
+







 * When resizing, sash positions are computed from the request sizes,
 * the available space, and pane weights (see PlaceSashes()).
 * This ensures continuous resize behavior (that is: changing
 * the size by X pixels then changing the size by Y pixels
 * gives the same result as changing the size by X+Y pixels
 * in one step).
 *
 * The request size is initially set to the slave window's requested size.
 * The request size is initially set to the content window's requested size.
 * When the user drags a sash, each pane's request size is set to its
 * actual size.  This ensures that panes "stay put" on the next resize.
 *
 * If reqSize == 0, use 0 for the weight as well.  This ensures that
 * "collapsed" panes stay collapsed during a resize, regardless of
 * their nominal -weight.
 *
73
74
75
76
77
78
79
80

81
82
83


84
85
86


87
88
89
90
91
92
93

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

111
112
113
114
115
116
117

118
119
120
121
122
123
124

125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

144
145
146
147
148
149
150
151

152
153
154
155
156
157
158
73
74
75
76
77
78
79

80
81


82
83
84


85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109

110
111
112
113
114
115
116

117
118
119
120
121
122
123

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

143
144
145
146
147
148
149
150

151
152
153
154
155
156
157
158







-
+

-
-
+
+

-
-
+
+






-
+
















-
+






-
+






-
+


















-
+







-
+







} Paned;

/* @@@ NOTE: -orient is readonly 'cause dynamic oriention changes NYI
 */
static const Tk_OptionSpec PanedOptionSpecs[] = {
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "vertical",
	offsetof(Paned,paned.orientObj), offsetof(Paned,paned.orient),
	0,(ClientData)ttkOrientStrings,READONLY_OPTION|STYLE_CHANGED },
	0, (void *)ttkOrientStrings, READONLY_OPTION|STYLE_CHANGED },
    {TK_OPTION_INT, "-width", "width", "Width", "0",
	TCL_INDEX_NONE, offsetof(Paned,paned.width),
	0,0,GEOMETRY_CHANGED },
	TCL_INDEX_NONE, offsetof(Paned, paned.width),
	0, 0, GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-height", "height", "Height", "0",
	TCL_INDEX_NONE, offsetof(Paned,paned.height),
	0,0,GEOMETRY_CHANGED },
	TCL_INDEX_NONE, offsetof(Paned, paned.height),
	0, 0, GEOMETRY_CHANGED },

    WIDGET_TAKEFOCUS_FALSE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

/*------------------------------------------------------------------------
 * +++ Slave pane record.
 * +++ Pane record.
 */
typedef struct {
    int 	reqSize;		/* Pane request size */
    int 	sashPos;		/* Folowing sash position */
    int 	weight; 		/* Pane -weight, for resizing */
} Pane;

static const Tk_OptionSpec PaneOptionSpecs[] = {
    {TK_OPTION_INT, "-weight", "weight", "Weight", "0",
	TCL_INDEX_NONE, offsetof(Pane,weight), 0,0,GEOMETRY_CHANGED },
    {TK_OPTION_END, 0,0,0, NULL, TCL_INDEX_NONE,TCL_INDEX_NONE, 0,0,0}
};

/* CreatePane --
 * 	Create a new pane record.
 */
static Pane *CreatePane(Tcl_Interp *interp, Paned *pw, Tk_Window slaveWindow)
static Pane *CreatePane(Tcl_Interp *interp, Paned *pw, Tk_Window window)
{
    Tk_OptionTable optionTable = pw->paned.paneOptionTable;
    void *record = ckalloc(sizeof(Pane));
    Pane *pane = (Pane *)record;

    memset(record, 0, sizeof(Pane));
    if (Tk_InitOptions(interp, record, optionTable, slaveWindow) != TCL_OK) {
    if (Tk_InitOptions(interp, record, optionTable, window) != TCL_OK) {
	ckfree(record);
	return NULL;
    }

    pane->reqSize
	= pw->paned.orient == TTK_ORIENT_HORIZONTAL
	? Tk_ReqWidth(slaveWindow) : Tk_ReqHeight(slaveWindow);
	? Tk_ReqWidth(window) : Tk_ReqHeight(window);

    return pane;
}

/* DestroyPane --
 * 	Free pane record.
 */
static void DestroyPane(Paned *pw, Pane *pane)
{
    void *record = pane;
    Tk_FreeConfigOptions(record, pw->paned.paneOptionTable, pw->core.tkwin);
    ckfree(record);
}

/* ConfigurePane --
 * 	Set pane options.
 */
static int ConfigurePane(
    Tcl_Interp *interp, Paned *pw, Pane *pane, Tk_Window slaveWindow,
    Tcl_Interp *interp, Paned *pw, Pane *pane, Tk_Window window,
    int objc, Tcl_Obj *const objv[])
{
    Ttk_Manager *mgr = pw->paned.mgr;
    Tk_SavedOptions savedOptions;
    int mask = 0;

    if (Tk_SetOptions(interp, pane, pw->paned.paneOptionTable,
	    objc, objv, slaveWindow, &savedOptions, &mask) != TCL_OK)
	    objc, objv, window, &savedOptions, &mask) != TCL_OK)
    {
	return TCL_ERROR;
    }

    /* Sanity-check:
     */
    if (pane->weight < 0) {
184
185
186
187
188
189
190
191

192
193
194
195
196
197
198

199
200
201
202
203
204
205
206
207
208
209
210
211

212
213
214
215


216
217

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

234
235
236
237
238
239
240
241
242


243
244
245


246
247
248
249
250
251
252


253
254
255


256
257
258
259
260
261
262
184
185
186
187
188
189
190

191
192
193
194
195
196
197

198
199
200
201
202
203
204
205
206
207
208
209
210

211
212
213


214
215
216

217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

233
234
235
236
237
238
239
240


241
242
243


244
245
246
247
248
249
250


251
252
253


254
255
256
257
258
259
260
261
262







-
+






-
+












-
+


-
-
+
+

-
+















-
+







-
-
+
+

-
-
+
+





-
-
+
+

-
-
+
+







 * 	of the window.  If that happens, shove back down.
 *
 * 	Returns: final position of sash i.
 */

static int ShoveUp(Paned *pw, int i, int pos)
{
    Pane *pane = (Pane *)Ttk_SlaveData(pw->paned.mgr, i);
    Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr, i);
    int sashThickness = pw->paned.sashThickness;

    if (i == 0) {
	if (pos < 0)
	    pos = 0;
    } else {
	Pane *prevPane = (Pane *)Ttk_SlaveData(pw->paned.mgr, i-1);
	Pane *prevPane = (Pane *)Ttk_ContentData(pw->paned.mgr, i-1);
	if (pos < prevPane->sashPos + sashThickness)
	    pos = ShoveUp(pw, i-1, pos - sashThickness) + sashThickness;
    }
    return pane->sashPos = pos;
}

/* ShoveDown --
 * 	Same as ShoveUp, but going in the opposite direction
 * 	and stopping at the sentinel sash.
 */
static int ShoveDown(Paned *pw, TkSizeT i, int pos)
{
    Pane *pane = (Pane *)Ttk_SlaveData(pw->paned.mgr,i);
    Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr,i);
    int sashThickness = pw->paned.sashThickness;

    if (i == Ttk_NumberSlaves(pw->paned.mgr) - 1) {
	pos = pane->sashPos; /* Sentinel value == master window size */
    if (i == Ttk_NumberContent(pw->paned.mgr) - 1) {
	pos = pane->sashPos; /* Sentinel value == container window size */
    } else {
	Pane *nextPane = (Pane *)Ttk_SlaveData(pw->paned.mgr,i+1);
	Pane *nextPane = (Pane *)Ttk_ContentData(pw->paned.mgr,i+1);
	if (pos + sashThickness > nextPane->sashPos)
	    pos = ShoveDown(pw, i+1, pos + sashThickness) - sashThickness;
    }
    return pane->sashPos = pos;
}

/* PanedSize --
 * 	Compute the requested size of the paned widget
 * 	from the individual pane request sizes.
 *
 * 	Used as the WidgetSpec sizeProc and the ManagerSpec sizeProc.
 */
static int PanedSize(void *recordPtr, int *widthPtr, int *heightPtr)
{
    Paned *pw = (Paned *)recordPtr;
    int nPanes = Ttk_NumberSlaves(pw->paned.mgr);
    int nPanes = Ttk_NumberContent(pw->paned.mgr);
    int nSashes = nPanes - 1;
    int sashThickness = pw->paned.sashThickness;
    int width = 0, height = 0;
    int index;

    if (pw->paned.orient == TTK_ORIENT_HORIZONTAL) {
	for (index = 0; index < nPanes; ++index) {
	    Pane *pane = (Pane *)Ttk_SlaveData(pw->paned.mgr, index);
	    Tk_Window slaveWindow = Ttk_SlaveWindow(pw->paned.mgr, index);
	    Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr, index);
	    Tk_Window window = Ttk_ContentWindow(pw->paned.mgr, index);

	    if (height < Tk_ReqHeight(slaveWindow))
		height = Tk_ReqHeight(slaveWindow);
	    if (height < Tk_ReqHeight(window))
		height = Tk_ReqHeight(window);
	    width += pane->reqSize;
	}
	width += nSashes * sashThickness;
    } else {
	for (index = 0; index < nPanes; ++index) {
	    Pane *pane = (Pane *)Ttk_SlaveData(pw->paned.mgr, index);
	    Tk_Window slaveWindow = Ttk_SlaveWindow(pw->paned.mgr, index);
	    Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr, index);
	    Tk_Window window = Ttk_ContentWindow(pw->paned.mgr, index);

	    if (width < Tk_ReqWidth(slaveWindow))
		width = Tk_ReqWidth(slaveWindow);
	    if (width < Tk_ReqWidth(window))
		width = Tk_ReqWidth(window);
	    height += pane->reqSize;
	}
	height += nSashes * sashThickness;
    }

    *widthPtr = pw->paned.width > 0 ? pw->paned.width : width;
    *heightPtr = pw->paned.height > 0 ? pw->paned.height : height;
273
274
275
276
277
278
279
280
281


282
283
284
285
286
287
288
273
274
275
276
277
278
279


280
281
282
283
284
285
286
287
288







-
-
+
+







 */
static void AdjustPanes(Paned *pw)
{
    int sashThickness = pw->paned.sashThickness;
    int pos = 0;
    TkSizeT index;

    for (index = 0; index < Ttk_NumberSlaves(pw->paned.mgr); ++index) {
	Pane *pane = (Pane *)Ttk_SlaveData(pw->paned.mgr, index);
    for (index = 0; index < Ttk_NumberContent(pw->paned.mgr); ++index) {
	Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr, index);
	int size = pane->sashPos - pos;
	pane->reqSize = size >= 0 ? size : 0;
	pos = pane->sashPos + sashThickness;
    }
}

/* PlaceSashes --
300
301
302
303
304
305
306
307

308
309
310
311
312
313
314
315
316
317
318
319

320
321
322
323
324
325
326
300
301
302
303
304
305
306

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

319
320
321
322
323
324
325
326







-
+











-
+







 * Notes:
 * 	This doesn't distribute the remainder pixels as evenly as it could
 * 	when more than one pane has weight > 1.
 */
static void PlaceSashes(Paned *pw, int width, int height)
{
    Ttk_Manager *mgr = pw->paned.mgr;
    int nPanes = Ttk_NumberSlaves(mgr);
    int nPanes = Ttk_NumberContent(mgr);
    int sashThickness = pw->paned.sashThickness;
    int available = pw->paned.orient == TTK_ORIENT_HORIZONTAL ? width : height;
    int reqSize = 0, totalWeight = 0;
    int difference, delta, remainder, pos, i;

    if (nPanes == 0)
	return;

    /* Compute total required size and total available weight:
     */
    for (i = 0; i < nPanes; ++i) {
	Pane *pane = (Pane *)Ttk_SlaveData(mgr, i);
	Pane *pane = (Pane *)Ttk_ContentData(mgr, i);
	reqSize += pane->reqSize;
	totalWeight += pane->weight * (pane->reqSize != 0);
    }

    /* Compute difference to be redistributed:
     */
    difference = available - reqSize - sashThickness*(nPanes-1);
336
337
338
339
340
341
342
343

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

343
344
345
346
347
348
349
350







-
+







    }
    /* ASSERT: 0 <= remainder < totalWeight */

    /* Place sashes:
     */
    pos = 0;
    for (i = 0; i < nPanes; ++i) {
	Pane *pane = (Pane *)Ttk_SlaveData(mgr, i);
	Pane *pane = (Pane *)Ttk_ContentData(mgr, i);
	int weight = pane->weight * (pane->reqSize != 0);
	int size = pane->reqSize + delta * weight;

	if (weight > remainder)
	    weight = remainder;
	remainder -= weight;
	size += weight;
360
361
362
363
364
365
366
367

368
369
370
371
372
373
374
375
376
377
378


379
380
381
382
383

384
385

386
387
388

389
390
391
392
393
394
395
396
397
398
399

400
401
402
403
404
405
406
407
408
409

410
411
412
413
414
415

416
417
418
419

420
421
422

423
424

425
426
427
428
429

430
431
432
433

434
435
436
437
438

439
440
441
442
443
444


445
446
447
448
449
450
451
452


453
454
455

456
457
458
459
460
461
462

463
464

465
466
467
468
469
470
471
360
361
362
363
364
365
366

367
368
369
370
371
372
373
374
375
376


377
378
379
380
381
382

383
384

385
386
387

388
389
390
391
392
393
394
395
396
397
398

399
400
401
402
403
404
405
406
407
408

409
410
411
412
413
414

415
416
417
418

419
420
421

422
423

424
425
426
427
428

429
430
431
432

433
434
435
436
437

438
439
440
441
442


443
444
445
446
447
448
449
450


451
452
453
454

455
456
457
458
459
460
461

462
463

464
465
466
467
468
469
470
471







-
+









-
-
+
+




-
+

-
+


-
+










-
+









-
+





-
+



-
+


-
+

-
+




-
+



-
+




-
+




-
-
+
+






-
-
+
+


-
+






-
+

-
+







     * Set sentinel sash position to end of widget,
     * shove preceding sashes up.
     */
    ShoveUp(pw, nPanes - 1, available);
}

/* PlacePanes --
 *	Places slave panes based on sash positions.
 *	Places panes based on sash positions.
 */
static void PlacePanes(Paned *pw)
{
    int horizontal = pw->paned.orient == TTK_ORIENT_HORIZONTAL;
    int width = Tk_Width(pw->core.tkwin), height = Tk_Height(pw->core.tkwin);
    int sashThickness = pw->paned.sashThickness;
    int pos = 0;
    TkSizeT index;

    for (index = 0; index < Ttk_NumberSlaves(pw->paned.mgr); ++index) {
	Pane *pane = (Pane *)Ttk_SlaveData(pw->paned.mgr, index);
    for (index = 0; index < Ttk_NumberContent(pw->paned.mgr); ++index) {
	Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr, index);
	int size = pane->sashPos - pos;

	if (size > 0) {
	    if (horizontal) {
		Ttk_PlaceSlave(pw->paned.mgr, index, pos, 0, size, height);
		Ttk_PlaceContent(pw->paned.mgr, index, pos, 0, size, height);
	    } else {
		Ttk_PlaceSlave(pw->paned.mgr, index, 0, pos, width, size);
		Ttk_PlaceContent(pw->paned.mgr, index, 0, pos, width, size);
	    }
	} else {
	    Ttk_UnmapSlave(pw->paned.mgr, index);
	    Ttk_UnmapContent(pw->paned.mgr, index);
	}

	pos = pane->sashPos + sashThickness;
    }
}

/*------------------------------------------------------------------------
 * +++ Manager specification.
 */

static void PanedPlaceSlaves(void *managerData)
static void PanedPlaceContent(void *managerData)
{
    Paned *pw = (Paned *)managerData;
    PlaceSashes(pw, Tk_Width(pw->core.tkwin), Tk_Height(pw->core.tkwin));
    PlacePanes(pw);
}

static void PaneRemoved(void *managerData, TkSizeT index)
{
    Paned *pw = (Paned *)managerData;
    Pane *pane = (Pane *)Ttk_SlaveData(pw->paned.mgr, index);
    Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr, index);
    DestroyPane(pw, pane);
}

static int AddPane(
    Tcl_Interp *interp, Paned *pw,
    int destIndex, Tk_Window slaveWindow,
    int destIndex, Tk_Window window,
    int objc, Tcl_Obj *const objv[])
{
    Pane *pane;
    if (!Ttk_Maintainable(interp, slaveWindow, pw->core.tkwin)) {
    if (!Ttk_Maintainable(interp, window, pw->core.tkwin)) {
	return TCL_ERROR;
    }
    if (Ttk_SlaveIndex(pw->paned.mgr, slaveWindow) != TCL_INDEX_NONE) {
    if (Ttk_ContentIndex(pw->paned.mgr, window) != TCL_INDEX_NONE) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"%s already added", Tk_PathName(slaveWindow)));
		"%s already added", Tk_PathName(window)));
	Tcl_SetErrorCode(interp, "TTK", "PANE", "PRESENT", NULL);
	return TCL_ERROR;
    }

    pane = CreatePane(interp, pw, slaveWindow);
    pane = CreatePane(interp, pw, window);
    if (!pane) {
	return TCL_ERROR;
    }
    if (ConfigurePane(interp, pw, pane, slaveWindow, objc, objv) != TCL_OK) {
    if (ConfigurePane(interp, pw, pane, window, objc, objv) != TCL_OK) {
	DestroyPane(pw, pane);
	return TCL_ERROR;
    }

    Ttk_InsertSlave(pw->paned.mgr, destIndex, slaveWindow, pane);
    Ttk_InsertContent(pw->paned.mgr, destIndex, window, pane);
    return TCL_OK;
}

/* PaneRequest --
 * 	Only update pane request size if slave is currently unmapped.
 * 	Geometry requests from mapped slaves are not directly honored
 * 	Only update pane request size if pane is currently unmapped.
 * 	Geometry requests from mapped panes are not directly honored
 * 	in order to avoid unexpected pane resizes (esp. while the
 * 	user is dragging a sash [#1325286]).
 */
static int PaneRequest(void *managerData, TkSizeT index, int width, int height)
{
    Paned *pw = (Paned *)managerData;
    Pane *pane = (Pane *)Ttk_SlaveData(pw->paned.mgr, index);
    Tk_Window slaveWindow = Ttk_SlaveWindow(pw->paned.mgr, index);
    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(slaveWindow)) {
    if (!Tk_IsMapped(window)) {
	pane->reqSize = horizontal ? width : height;
    }
    return 1;
}

static Ttk_ManagerSpec PanedManagerSpec = {
    { "panedwindow", Ttk_GeometryRequestProc, Ttk_LostSlaveProc },
    { "panedwindow", Ttk_GeometryRequestProc, Ttk_LostContentProc },
    PanedSize,
    PanedPlaceSlaves,
    PanedPlaceContent,
    PaneRequest,
    PaneRemoved
};

/*------------------------------------------------------------------------
 * +++ Event handler.
 *
482
483
484
485
486
487
488
489

490
491
492
493
494
495
496
482
483
484
485
486
487
488

489
490
491
492
493
494
495
496







-
+







static const unsigned PanedEventMask = LeaveWindowMask;
static void PanedEventProc(ClientData clientData, XEvent *eventPtr)
{
    WidgetCore *corePtr = (WidgetCore *)clientData;
    if (   eventPtr->type == LeaveNotify
	&& eventPtr->xcrossing.detail == NotifyInferior)
    {
	TtkSendVirtualEvent(corePtr->tkwin, "EnteredChild");
	Tk_SendVirtualEvent(corePtr->tkwin, "EnteredChild", NULL);
    }
}

/*------------------------------------------------------------------------
 * +++ Initialization and cleanup hooks.
 */

515
516
517
518
519
520
521
522




523
524
525
526
527
528
529
530
531
532
515
516
517
518
519
520
521

522
523
524
525
526
527

528
529
530
531
532
533
534







-
+
+
+
+


-







    Tk_DeleteEventHandler(pw->core.tkwin,
	PanedEventMask, PanedEventProc, recordPtr);
    Ttk_DeleteManager(pw->paned.mgr);
}

/* Post-configuration hook.
 */
static int PanedPostConfigure(Tcl_Interp *dummy, void *clientData, int mask)
static int PanedPostConfigure(
    TCL_UNUSED(Tcl_Interp *),
    void *clientData,
    int mask)
{
    Paned *pw = (Paned *)clientData;
    (void)dummy;

    if (mask & GEOMETRY_CHANGED) {
	/* User has changed -width or -height.
	 * Recalculate sash positions based on requested size.
	 */
	Tk_Window tkwin = pw->core.tkwin;
	PlaceSashes(pw,
577
578
579
580
581
582
583
584

585
586
587
588
589
590
591
579
580
581
582
583
584
585

586
587
588
589
590
591
592
593







-
+








/* SashLayout --
 * 	Place the sash sublayout after the specified pane,
 * 	in preparation for drawing.
 */
static Ttk_Layout SashLayout(Paned *pw, int index)
{
    Pane *pane = (Pane *)Ttk_SlaveData(pw->paned.mgr, index);
    Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr, index);
    int thickness = pw->paned.sashThickness,
	height = Tk_Height(pw->core.tkwin),
	width = Tk_Width(pw->core.tkwin),
	sashPos = pane->sashPos;

    Ttk_PlaceLayout(
	pw->paned.sashLayout, pw->core.state,
600
601
602
603
604
605
606
607

608
609
610

611
612
613
614
615
616
617
618
619
620
621
622
623
624
625

626
627
628
629
630
631
632

633
634
635

636
637
638
639

640
641
642
643
644


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
602
603
604
605
606
607
608

609
610
611

612
613
614
615
616
617
618
619
620
621
622
623
624
625
626

627
628
629
630
631
632
633

634
635
636

637
638
639
640

641
642
643
644


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







-
+


-
+














-
+






-
+


-
+



-
+



-
-
+
+





-
+

-
+


-
+



-
+

-
+



-
+





-
-
-
-
+
+
+
+

-
-
-
+
+
+



-
-
+
+
















-
+



-
-
+
+

-
+















-
+


















-
+







{
    Ttk_DrawLayout(SashLayout(pw, index), pw->core.state, d);
}

static void PanedDisplay(void *recordPtr, Drawable d)
{
    Paned *pw = (Paned *)recordPtr;
    TkSizeT i, nSlaves = Ttk_NumberSlaves(pw->paned.mgr);
    TkSizeT i, nContent = Ttk_NumberContent(pw->paned.mgr);

    TtkWidgetDisplay(recordPtr, d);
    for (i = 1; i < nSlaves; ++i) {
    for (i = 1; i < nContent; ++i) {
	DrawSash(pw, i - 1, d);
    }
}

/*------------------------------------------------------------------------
 * +++ Widget commands.
 */

/* $pw add window [ options ... ]
 */
static int PanedAddCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Paned *pw = (Paned *)recordPtr;
    Tk_Window slaveWindow;
    Tk_Window window;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }

    slaveWindow = Tk_NameToWindow(
    window = Tk_NameToWindow(
	interp, Tcl_GetString(objv[2]), pw->core.tkwin);

    if (!slaveWindow) {
    if (!window) {
	return TCL_ERROR;
    }

    return AddPane(interp, pw, Ttk_NumberSlaves(pw->paned.mgr), slaveWindow,
    return AddPane(interp, pw, Ttk_NumberContent(pw->paned.mgr), window,
	    objc - 3, objv + 3);
}

/* $pw insert $index $slave ?-option value ...?
 * 	Insert new slave, or move existing one.
/* $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 nSlaves = Ttk_NumberSlaves(pw->paned.mgr);
    TkSizeT nContent = Ttk_NumberContent(pw->paned.mgr);
    TkSizeT srcIndex, destIndex;
    Tk_Window slaveWindow;
    Tk_Window window;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2,objv, "index slave ?-option value ...?");
	Tcl_WrongNumArgs(interp, 2,objv, "index window ?-option value ...?");
	return TCL_ERROR;
    }

    slaveWindow = Tk_NameToWindow(
    window = Tk_NameToWindow(
	interp, Tcl_GetString(objv[3]), pw->core.tkwin);
    if (!slaveWindow) {
    if (!window) {
	return TCL_ERROR;
    }

    if (TCL_OK != Ttk_GetSlaveIndexFromObj(
    if (TCL_OK != Ttk_GetContentIndexFromObj(
		interp,pw->paned.mgr, objv[2], &destIndex))
    {
	return TCL_ERROR;
    }

    srcIndex = Ttk_SlaveIndex(pw->paned.mgr, slaveWindow);
    if (srcIndex == TCL_INDEX_NONE) { /* New slave: */
	return AddPane(interp, pw, destIndex, slaveWindow, objc-4, objv+4);
    } /* else -- move existing slave: */
    srcIndex = Ttk_ContentIndex(pw->paned.mgr, window);
    if (srcIndex == TCL_INDEX_NONE) { /* New content: */
	return AddPane(interp, pw, destIndex, window, objc-4, objv+4);
    } /* else -- move existing content: */

    if (destIndex + 1 >= nSlaves + 1)
	destIndex  = nSlaves - 1;
    Ttk_ReorderSlave(pw->paned.mgr, srcIndex, destIndex);
    if (destIndex + 1 >= nContent + 1)
	destIndex  = nContent - 1;
    Ttk_ReorderContent(pw->paned.mgr, srcIndex, destIndex);

    return objc == 4 ? TCL_OK :
	ConfigurePane(interp, pw,
		(Pane *)Ttk_SlaveData(pw->paned.mgr, destIndex),
		Ttk_SlaveWindow(pw->paned.mgr, destIndex),
		(Pane *)Ttk_ContentData(pw->paned.mgr, destIndex),
		Ttk_ContentWindow(pw->paned.mgr, destIndex),
		objc-4, objv+4);
}

/* $pw forget $pane
 */
static int PanedForgetCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Paned *pw = (Paned *)recordPtr;
    TkSizeT paneIndex;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2,objv, "pane");
	return TCL_ERROR;
    }

    if (TCL_OK != Ttk_GetSlaveIndexFromObj(
    if (TCL_OK != Ttk_GetContentIndexFromObj(
		    interp, pw->paned.mgr, objv[2], &paneIndex))
    {
	return TCL_ERROR;
    } else if (paneIndex + 1 >= Ttk_NumberSlaves(pw->paned.mgr) + 1) {
	paneIndex = Ttk_NumberSlaves(pw->paned.mgr) - 1;
    } else if (paneIndex + 1 >= Ttk_NumberContent(pw->paned.mgr) + 1) {
	paneIndex = Ttk_NumberContent(pw->paned.mgr) - 1;
    }
    Ttk_ForgetSlave(pw->paned.mgr, paneIndex);
    Ttk_ForgetContent(pw->paned.mgr, paneIndex);

    return TCL_OK;
}

/* $pw identify ?what? $x $y --
 * 	Return index of sash at $x,$y
 */
static int PanedIdentifyCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    static const char *const whatTable[] = { "element", "sash", NULL };
    enum { IDENTIFY_ELEMENT, IDENTIFY_SASH };
    int what = IDENTIFY_SASH;
    Paned *pw = (Paned *)recordPtr;
    int sashThickness = pw->paned.sashThickness;
    int nSashes = Ttk_NumberSlaves(pw->paned.mgr) - 1;
    int nSashes = Ttk_NumberContent(pw->paned.mgr) - 1;
    int x, y, pos;
    int index;

    if (objc < 4 || objc > 5) {
	Tcl_WrongNumArgs(interp, 2,objv, "?what? x y");
	return TCL_ERROR;
    }

    if (   Tcl_GetIntFromObj(interp, objv[objc-2], &x) != TCL_OK
	|| Tcl_GetIntFromObj(interp, objv[objc-1], &y) != TCL_OK
	|| (objc == 5 && Tcl_GetIndexFromObjStruct(interp, objv[2], whatTable,
	    sizeof(char *), "option", 0, &what) != TCL_OK)
    ) {
	return TCL_ERROR;
    }

    pos = pw->paned.orient == TTK_ORIENT_HORIZONTAL ? x : y;
    for (index = 0; index < nSashes; ++index) {
	Pane *pane = (Pane *)Ttk_SlaveData(pw->paned.mgr, index);
	Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr, index);
	if (pane->sashPos <= pos && pos <= pane->sashPos + sashThickness) {
	    /* Found it. */
	    switch (what) {
		case IDENTIFY_SASH:
		    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index));
		    return TCL_OK;
		case IDENTIFY_ELEMENT:
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
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







-
+







-
+



-
-
+
+


-
-
+
+




-
+


-
+

-
+




















-
-
+
+







 * 	Query/modify pane options.
 */
static int PanedPaneCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Paned *pw = (Paned *)recordPtr;
    TkSizeT paneIndex;
    Tk_Window slaveWindow;
    Tk_Window window;
    Pane *pane;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2,objv, "pane ?-option value ...?");
	return TCL_ERROR;
    }

    if (TCL_OK != Ttk_GetSlaveIndexFromObj(
    if (TCL_OK != Ttk_GetContentIndexFromObj(
		    interp,pw->paned.mgr, objv[2], &paneIndex))
    {
	return TCL_ERROR;
    } else if (paneIndex + 1 >= Ttk_NumberSlaves(pw->paned.mgr) + 1) {
	paneIndex = Ttk_NumberSlaves(pw->paned.mgr) - 1;
    } else if (paneIndex + 1 >= Ttk_NumberContent(pw->paned.mgr) + 1) {
	paneIndex = Ttk_NumberContent(pw->paned.mgr) - 1;
    }

    pane = (Pane *)Ttk_SlaveData(pw->paned.mgr, paneIndex);
    slaveWindow = Ttk_SlaveWindow(pw->paned.mgr, paneIndex);
    pane = (Pane *)Ttk_ContentData(pw->paned.mgr, paneIndex);
    window = Ttk_ContentWindow(pw->paned.mgr, paneIndex);

    switch (objc) {
	case 3:
	    return TtkEnumerateOptions(interp, pane, PaneOptionSpecs,
			pw->paned.paneOptionTable, slaveWindow);
			pw->paned.paneOptionTable, window);
	case 4:
	    return TtkGetOptionValue(interp, pane, objv[3],
			pw->paned.paneOptionTable, slaveWindow);
			pw->paned.paneOptionTable, window);
	default:
	    return ConfigurePane(interp, pw, pane, slaveWindow, objc-3,objv+3);
	    return ConfigurePane(interp, pw, pane, window, objc-3,objv+3);
    }
}

/* $pw panes --
 * 	Return list of managed panes.
 */
static int PanedPanesCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Paned *pw = (Paned *)recordPtr;
    Ttk_Manager *mgr = pw->paned.mgr;
    Tcl_Obj *panes;
    TkSizeT i;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, "");
	return TCL_ERROR;
    }

    panes = Tcl_NewListObj(0, NULL);
    for (i = 0; i < Ttk_NumberSlaves(mgr); ++i) {
	const char *pathName = Tk_PathName(Ttk_SlaveWindow(mgr,i));
    for (i = 0; i < Ttk_NumberContent(mgr); ++i) {
	const char *pathName = Tk_PathName(Ttk_ContentWindow(mgr,i));
	Tcl_ListObjAppendElement(interp, panes, Tcl_NewStringObj(pathName,-1));
    }
    Tcl_SetObjResult(interp, panes);

    return TCL_OK;
}

842
843
844
845
846
847
848
849

850
851
852
853
854
855
856

857
858
859
860
861
862
863
844
845
846
847
848
849
850

851
852
853
854
855
856
857

858
859
860
861
862
863
864
865







-
+






-
+







    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_NumberSlaves(pw->paned.mgr)) {
    if (sashIndex < 0 || (TkSizeT)sashIndex + 1 >= Ttk_NumberContent(pw->paned.mgr)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "sash index %d out of range", sashIndex));
	Tcl_SetErrorCode(interp, "TTK", "PANE", "SASH_INDEX", NULL);
	return TCL_ERROR;
    }

    pane = (Pane *)Ttk_SlaveData(pw->paned.mgr, sashIndex);
    pane = (Pane *)Ttk_ContentData(pw->paned.mgr, sashIndex);

    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(pane->sashPos));
	return TCL_OK;
    }
    /* else -- set new sash position */

876
877
878
879
880
881
882
883
884

885
886
887
888
889
890
891
892

893
894
895
896
897
898
899
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







-

+








+








    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(pane->sashPos));
    return TCL_OK;
}

static const Ttk_Ensemble PanedCommands[] = {
    { "add", 		PanedAddCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "forget", 	PanedForgetCommand,0 },
    { "identify", 	PanedIdentifyCommand,0 },
    { "insert", 	PanedInsertCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "pane",   	PanedPaneCommand,0 },
    { "panes",   	PanedPanesCommand,0 },
    { "sashpos",  	PanedSashposCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    { 0,0,0 }
};

/*------------------------------------------------------------------------
 * +++ Widget specification.
 */

926
927
928
929
930
931
932

933
934





935
936
937
938
939
940
941
942
943
944
945
946
947
929
930
931
932
933
934
935
936


937
938
939
940
941
942
943
944



945
946
947
948
949
950
951







+
-
-
+
+
+
+
+



-
-
-







static const Ttk_ElementOptionSpec SashElementOptions[] = {
    { "-sashthickness", TK_OPTION_INT,
	    offsetof(SashElement,thicknessObj), "5" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SashElementSize(
    TCL_UNUSED(void *),
    void *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 *))
{
    SashElement *sash = (SashElement *)elementRecord;
    int thickness = DEFAULT_SASH_THICKNESS;
    (void)dummy;
    (void)tkwin;
    (void)paddingPtr;

    Tcl_GetIntFromObj(NULL, sash->thicknessObj, &thickness);
    *widthPtr = *heightPtr = thickness;
}

static const Ttk_ElementSpec SashElementSpec = {
    TK_STYLE_VERSION_2,

Changes to generic/ttk/ttkProgress.c.

1
2

3
4
5
6
7
8
9
1

2
3
4
5
6
7
8
9

-
+







/*
 * Copyright (c) Joe English, Pat Thoyts, Michael Kirkham
 * Copyright © Joe English, Pat Thoyts, Michael Kirkham
 *
 * ttk::progressbar widget.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
67
68
69
70
71
72
73
74

75
76
77

78
79
80
81
82
83
84
67
68
69
70
71
72
73

74
75
76

77
78
79
80
81
82
83
84







-
+


-
+







	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, (ClientData)ProgressbarModeStrings, 0 },
	0, (void *)ProgressbarModeStrings, 0 },
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient",
	"horizontal", offsetof(Progressbar,progress.orientObj), TCL_INDEX_NONE,
	0, (ClientData)ttkOrientStrings, STYLE_CHANGED },
	0, (void *)ttkOrientStrings, STYLE_CHANGED },
    {TK_OPTION_INT, "-phase", "phase", "Phase",
	"0", offsetof(Progressbar,progress.phaseObj), TCL_INDEX_NONE,
	0, 0, 0 },
    {TK_OPTION_STRING, "-text", "text", "Text", "",
	offsetof(Progressbar,progress.textObj), TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_DOUBLE, "-value", "value", "Value",
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

136
137
138



139
140

141
142
143
144
145

146
147
148
149
150
151
152
153
154
155
121
122
123
124
125
126
127

128
129
130
131
132
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 reschedules itself if animation still enabled.
 */
static void AnimateProgressProc(ClientData clientData)
{
    Progressbar *pb = (Progressbar *)clientData;

    pb->progress.timer = 0;

    if (AnimationEnabled(pb)) {
	int phase = 0;
	Tcl_GetIntFromObj(NULL, pb->progress.phaseObj, &phase);

	/*
	 * Update -phase:
	 */

	++phase;
	if (pb->progress.maxPhase)
	    phase %= pb->progress.maxPhase;
	if (phase > pb->progress.maxPhase) {
	    phase = 0;
	}
	Tcl_DecrRefCount(pb->progress.phaseObj);
	pb->progress.phaseObj = Tcl_NewIntObj(phase);
	pb->progress.phaseObj = Tcl_NewWideIntObj(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.
204
205
206
207
208
209
210
211



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

212
213
214
215
216

217
218
219
220
221
222
223







-
+
+
+


-







    TtkRedisplayWidget(&pb->core);
}

/*------------------------------------------------------------------------
 * +++ Widget class methods:
 */

static void ProgressbarInitialize(Tcl_Interp *dummy, void *recordPtr)
static void ProgressbarInitialize(
    TCL_UNUSED(Tcl_Interp *),
    void *recordPtr)
{
    Progressbar *pb = (Progressbar *)recordPtr;
    (void)dummy;

    pb->progress.variableTrace = 0;
    pb->progress.timer = 0;
}

static void ProgressbarCleanup(void *recordPtr)
{
255
256
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
275
276







+
-
+
+



-
-







    return TCL_OK;
}

/*
 * Post-configuration hook:
 */
static int ProgressbarPostConfigure(
    TCL_UNUSED(Tcl_Interp *),
    Tcl_Interp *dummy, void *recordPtr, int mask)
    void *recordPtr,
    TCL_UNUSED(int))
{
    Progressbar *pb = (Progressbar *)recordPtr;
    int status = TCL_OK;
    (void)dummy;
    (void)mask;

    if (pb->progress.variableTrace) {
	status = Ttk_FireTrace(pb->progress.variableTrace);
	if (WidgetDestroyed(&pb->core)) {
	    return TCL_ERROR;
	}
	if (status != TCL_OK) {
493
494
495
496
497
498
499

500

501
502
503



504
505

506
507
508

509

510
511
512



513
514

515
516
517
518
519

520
521
522
523
524
525

526
527
528
529
530
531
532
495
496
497
498
499
500
501
502

503



504
505
506
507

508
509
510
511
512

513



514
515
516
517

518
519
520
521

522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537







+
-
+
-
-
-
+
+
+

-
+



+
-
+
-
-
-
+
+
+

-
+



-

+






+







    status = Tcl_EvalObjEx(interp, cmd, 0);
    Tcl_DecrRefCount(cmd);

    return status;
}

static int ProgressbarStartCommand(
    TCL_UNUSED(void *),
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
    Tcl_Interp *interp,
{
    (void)recordPtr;

    int objc,
    Tcl_Obj *const objv[])
{
    return ProgressbarStartStopCommand(
	interp, "::ttk::progressbar::start", objc, objv);
	    interp, "::ttk::progressbar::start", objc, objv);
}

static int ProgressbarStopCommand(
    TCL_UNUSED(void *),
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
    Tcl_Interp *interp,
{
    (void)recordPtr;

    int objc,
    Tcl_Obj *const objv[])
{
    return ProgressbarStartStopCommand(
	interp, "::ttk::progressbar::stop", objc, objv);
	    interp, "::ttk::progressbar::stop", objc, objv);
}

static const Ttk_Ensemble ProgressbarCommands[] = {
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "start", 		ProgressbarStartCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "step", 		ProgressbarStepCommand,0 },
    { "stop", 		ProgressbarStopCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    { 0,0,0 }
};

/*
 * Widget specification:
 */
static const WidgetSpec ProgressbarWidgetSpec =

Changes to generic/ttk/ttkScale.c.

1
2

3
4
5
6
7
8
9
1

2
3
4
5
6
7
8
9

-
+







/*
 * Copyright (C) 2004 Pat Thoyts <[email protected]>
 * Copyright © 2004 Pat Thoyts <[email protected]>
 *
 * ttk::scale widget.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
53
54
55
56
57
58
59
60

61
62
63
64

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

79
80
81
82
83
84
85
53
54
55
56
57
58
59

60
61
62
63

64
65
66
67
68
69
70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85







-
+



-
+













-
+







static const Tk_OptionSpec ScaleOptionSpecs[] =
{
    {TK_OPTION_STRING, "-command", "command", "Command", "",
	offsetof(Scale,scale.commandObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0},
    {TK_OPTION_STRING, "-variable", "variable", "Variable", "",
	offsetof(Scale,scale.variableObj), TCL_INDEX_NONE,
	0,0,0},
	0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "horizontal",
	offsetof(Scale,scale.orientObj),
	offsetof(Scale,scale.orient), 0,
	(ClientData)ttkOrientStrings, STYLE_CHANGED },
	(void *)ttkOrientStrings, STYLE_CHANGED },

    {TK_OPTION_DOUBLE, "-from", "from", "From", "0",
	offsetof(Scale,scale.fromObj), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_DOUBLE, "-to", "to", "To", "1.0",
	offsetof(Scale,scale.toObj), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_DOUBLE, "-value", "value", "Value", "0",
	offsetof(Scale,scale.valueObj), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_PIXELS, "-length", "length", "Length",
	DEF_SCALE_LENGTH, offsetof(Scale,scale.lengthObj), TCL_INDEX_NONE, 0, 0,
    	GEOMETRY_CHANGED},

    {TK_OPTION_STRING, "-state", "state", "State",
	"normal", offsetof(Scale,scale.stateObj), TCL_INDEX_NONE,
        0,0,STATE_CHANGED},
        0, 0, STATE_CHANGED},

    WIDGET_TAKEFOCUS_TRUE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

static XPoint ValueToPoint(Scale *scalePtr, double value);
static double PointToValue(Scale *scalePtr, int x, int y);
106
107
108
109
110
111
112
113



114
115
116
117
118
119
120
121
122
123
106
107
108
109
110
111
112

113
114
115
116
117

118
119
120
121
122
123
124







-
+
+
+


-







    }
    TtkRedisplayWidget(&scale->core);
}

/* ScaleInitialize --
 * 	Scale widget initialization hook.
 */
static void ScaleInitialize(Tcl_Interp *dummy, void *recordPtr)
static void ScaleInitialize(
    TCL_UNUSED(Tcl_Interp *),
    void *recordPtr)
{
    Scale *scalePtr = (Scale *)recordPtr;
    (void)dummy;

    TtkTrackElementState(&scalePtr->core);
}

static void ScaleCleanup(void *recordPtr)
{
    Scale *scale = (Scale *)recordPtr;
159
160
161
162
163
164
165

166


167
168
169
170
171
172
173
174
175
176
177
178
160
161
162
163
164
165
166
167

168
169
170
171
172


173
174
175
176
177
178
179







+
-
+
+



-
-







    return TCL_OK;
}

/* ScalePostConfigure --
 * 	Post-configuration hook.
 */
static int ScalePostConfigure(
    TCL_UNUSED(Tcl_Interp *),
    Tcl_Interp *dummy, void *recordPtr, int mask)
    void *recordPtr,
    TCL_UNUSED(int))
{
    Scale *scale = (Scale *)recordPtr;
    int status = TCL_OK;
    (void)dummy;
    (void)mask;

    if (scale->scale.variableTrace) {
	status = Ttk_FireTrace(scale->scale.variableTrace);
	if (WidgetDestroyed(&scale->core)) {
	    return TCL_ERROR;
	}
	if (status != TCL_OK) {
372
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
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_NewIntObj(pt.x);
	point[1] = Tcl_NewIntObj(pt.y);
	point[0] = Tcl_NewWideIntObj(pt.x);
	point[1] = Tcl_NewWideIntObj(pt.y);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, point));
    }
    return r;
}

static void ScaleDoLayout(void *clientData)
{
477
478
479
480
481
482
483

484

485
486


487
488
489
490
491


492
493
494
495
496
497
498
478
479
480
481
482
483
484
485
486
487


488
489
490

491


492
493
494
495
496
497
498
499
500







+

+
-
-
+
+

-

-
-
+
+







	pt.x = troughBox.x + troughBox.width / 2;
	pt.y = troughBox.y + (int)(fraction * troughBox.height);
    }
    return pt;
}

static const Ttk_Ensemble ScaleCommands[] = {
    { "cget",        TtkWidgetCgetCommand,0 },
    { "configure",   TtkWidgetConfigureCommand,0 },
    { "coords",      ScaleCoordsCommand,0 },
    { "cget",        TtkWidgetCgetCommand,0 },
    { "state",       TtkWidgetStateCommand,0 },
    { "get",         ScaleGetCommand,0 },
    { "identify",    TtkWidgetIdentifyCommand,0 },
    { "instate",     TtkWidgetInstateCommand,0 },
    { "identify",    TtkWidgetIdentifyCommand,0 },
    { "set",         ScaleSetCommand,0 },
    { "get",         ScaleGetCommand,0 },
    { "coords",      ScaleCoordsCommand,0 },
    { "state",       TtkWidgetStateCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec ScaleWidgetSpec =
{
    "TScale",			/* Class name */
    sizeof(Scale),		/* record size */

Changes to generic/ttk/ttkScroll.c.

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((ClientData) interp);
    Tcl_Preserve(interp);
    code = UpdateScrollbar(interp, h);
    if (code == TCL_ERROR && !Tcl_InterpDeleted(interp)) {
	Tcl_BackgroundException(interp, code);
    }
    Tcl_Release((ClientData) interp);
    Tcl_Release(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, (ClientData)h);
	    Tcl_DoWhenIdle(UpdateScrollbarBG, h);
	    h->flags |= SCROLL_UPDATE_PENDING;
	}
    }
}

/* TtkScrollbarUpdateRequired --
 * 	Force a scrollbar update at the next call to TtkScrolled(),
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, (ClientData)h);
	Tcl_CancelIdleCall(UpdateScrollbarBG, h);
    }
    ckfree(h);
}

Changes to generic/ttk/ttkScrollbar.c.

1
2

3
4
5
6
7
8
9
1

2
3
4
5
6
7
8
9

-
+







/*
 * Copyright (c) 2003, Joe English
 * Copyright © 2003 Joe English
 *
 * ttk::scrollbar widget.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
30
31
32
33
34
35
36
37

38
39
40
41
42



43
44
45
46
47
48
49
50
51
52
53



54
55
56
57
58
59
60
61
62
63
30
31
32
33
34
35
36

37
38
39



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

53
54
55
56
57

58
59
60
61
62
63
64







-
+


-
-
-
+
+
+










-
+
+
+


-







    WidgetCore core;
    ScrollbarPart scrollbar;
} Scrollbar;

static const Tk_OptionSpec ScrollbarOptionSpecs[] =
{
    {TK_OPTION_STRING, "-command", "command", "Command", "",
	offsetof(Scrollbar,scrollbar.commandObj), TCL_INDEX_NONE, 0,0,0},
	offsetof(Scrollbar, scrollbar.commandObj), TCL_INDEX_NONE, 0, 0, 0},

    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "vertical",
	offsetof(Scrollbar,scrollbar.orientObj),
	offsetof(Scrollbar,scrollbar.orient),
	0,(ClientData)ttkOrientStrings,STYLE_CHANGED },
	offsetof(Scrollbar, scrollbar.orientObj),
	offsetof(Scrollbar, scrollbar.orient),
	0, (void *)ttkOrientStrings, STYLE_CHANGED },

    WIDGET_TAKEFOCUS_FALSE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

/*------------------------------------------------------------------------
 * +++ Widget hooks.
 */

static void
ScrollbarInitialize(Tcl_Interp *dummy, void *recordPtr)
ScrollbarInitialize(
    TCL_UNUSED(Tcl_Interp *),
    void *recordPtr)
{
    Scrollbar *sb = (Scrollbar *)recordPtr;
    (void)dummy;

    sb->scrollbar.first = 0.0;
    sb->scrollbar.last = 1.0;

    TtkTrackElementState(&sb->core);
}

277
278
279
280
281
282
283
284
285

286
287
288
289
290
291
292

293
294
295
296
297
298
299
278
279
280
281
282
283
284

285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301







-

+







+







    }

    Tcl_SetObjResult(interp, Tcl_NewDoubleObj(fraction));
    return TCL_OK;
}

static const Ttk_Ensemble ScrollbarCommands[] = {
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "delta",    	ScrollbarDeltaCommand,0 },
    { "fraction",    	ScrollbarFractionCommand,0 },
    { "get",    	ScrollbarGetCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "set",  		ScrollbarSetCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    { 0,0,0 }
};

/*------------------------------------------------------------------------
 * +++ Widget specification.
 */
static const WidgetSpec ScrollbarWidgetSpec =
312
313
314
315
316
317
318
319
320

321
322
323
324
325
326
327
328

329
330
331
332
333
334
335
314
315
316
317
318
319
320


321
322
323
324
325
326
327


328
329
330
331
332
333
334
335







-
-
+






-
-
+







    TtkWidgetDisplay		/* displayProc */
};

TTK_BEGIN_LAYOUT(VerticalScrollbarLayout)
    TTK_GROUP("Vertical.Scrollbar.trough", TTK_FILL_Y,
	TTK_NODE("Vertical.Scrollbar.uparrow", TTK_PACK_TOP)
	TTK_NODE("Vertical.Scrollbar.downarrow", TTK_PACK_BOTTOM)
	TTK_NODE(
	    "Vertical.Scrollbar.thumb", TTK_PACK_TOP|TTK_EXPAND|TTK_FILL_BOTH))
	TTK_NODE("Vertical.Scrollbar.thumb", TTK_FILL_BOTH))
TTK_END_LAYOUT

TTK_BEGIN_LAYOUT(HorizontalScrollbarLayout)
    TTK_GROUP("Horizontal.Scrollbar.trough", TTK_FILL_X,
	TTK_NODE("Horizontal.Scrollbar.leftarrow", TTK_PACK_LEFT)
	TTK_NODE("Horizontal.Scrollbar.rightarrow", TTK_PACK_RIGHT)
	TTK_NODE(
	"Horizontal.Scrollbar.thumb", TTK_PACK_LEFT|TTK_EXPAND|TTK_FILL_BOTH))
	TTK_NODE("Horizontal.Scrollbar.thumb", TTK_FILL_BOTH))
TTK_END_LAYOUT

/*------------------------------------------------------------------------
 * +++ Initialization.
 */

MODULE_SCOPE

Changes to generic/ttk/ttkSeparator.c.

1
2

3
4
5
6
7
8
9
1

2
3
4
5
6
7
8
9

-
+







/*
 * Copyright (c) 2004, Joe English
 * Copyright © 2004 Joe English
 *
 * ttk::separator and ttk::sizegrip widgets.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
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







-
+







    SeparatorPart separator;
} Separator;

static const Tk_OptionSpec SeparatorOptionSpecs[] = {
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "horizontal",
	offsetof(Separator,separator.orientObj),
	offsetof(Separator,separator.orient),
	0,(ClientData)ttkOrientStrings,STYLE_CHANGED },
	0, (void *)ttkOrientStrings, STYLE_CHANGED },

    WIDGET_TAKEFOCUS_FALSE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

/*
 * GetLayout hook --
44
45
46
47
48
49
50
51
52

53
54
55

56
57
58
59
60
61
62
44
45
46
47
48
49
50

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







-

+



+







	interp, theme, recordPtr, sep->separator.orientObj);
}

/*
 * Widget commands:
 */
static const Ttk_Ensemble SeparatorCommands[] = {
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    { 0,0,0 }
};

/*
 * Widget specification:
 */
static const WidgetSpec SeparatorWidgetSpec =
85
86
87
88
89
90
91
92
93

94
95
96

97
98
99
100
101
102
103
86
87
88
89
90
91
92

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







-

+



+








static const Tk_OptionSpec SizegripOptionSpecs[] = {
    WIDGET_TAKEFOCUS_FALSE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

static const Ttk_Ensemble SizegripCommands[] = {
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec SizegripWidgetSpec =
{
    "TSizegrip",		/* className */
    sizeof(WidgetCore),		/* recordSize */

Changes to generic/ttk/ttkSquare.c.

1

2
3
4
5
6
7
8

1
2
3
4
5
6
7
8
-
+







/* square.c - Copyright (C) 2004 Pat Thoyts <[email protected]>
/* square.c - Copyright © 2004 Pat Thoyts <[email protected]>
 *
 * Minimal sample ttk widget.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
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







-

+



+







/*
 * Widget commands. A widget is impelemented as an ensemble and the
 * subcommands are listed here. Ttk provides default implementations
 * that are sufficient for our needs.
 */

static const Ttk_Ensemble SquareCommands[] = {
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    { 0,0,0 }
};

/*
 * The Widget specification structure holds all the implementation
 * information about this widget and this is what must be registered
 * with Tk in the package initialization code (see bottom).
194
195
196
197
198
199
200

201
202





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

219
220





221
222
223
224
225
226
227
228
229
230
231
232
233
195
196
197
198
199
200
201
202


203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218
219
220
221
222
223


224
225
226
227
228
229
230
231
232


233
234
235
236
237
238
239







+
-
-
+
+
+
+
+



-












+
-
-
+
+
+
+
+




-
-







/*
 * The element geometry function is called when the layout code wishes to
 * find out how big this element wants to be. We must return our preferred
 * size and padding information
 */

static void SquareElementSize(
    TCL_UNUSED(void *),
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    Ttk_Padding *paddingPtr)
{
    SquareElement *square = (SquareElement *)elementRecord;
    int borderWidth = 0;
    (void)dummy;

    Tcl_GetIntFromObj(NULL, square->borderWidthObj, &borderWidth);
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
    Tk_GetPixelsFromObj(NULL, tkwin, square->widthObj, widthPtr);
    Tk_GetPixelsFromObj(NULL, tkwin, square->heightObj, heightPtr);
}

/*
 * Draw the element in the box provided.
 */

static void SquareElementDraw(
    TCL_UNUSED(void *),
    void *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(unsigned int))
{
    SquareElement *square = (SquareElement *)elementRecord;
    Tk_3DBorder foreground = NULL;
    int borderWidth = 1, relief = TK_RELIEF_FLAT;
    (void)dummy;
    (void)state;

    foreground = Tk_Get3DBorderFromObj(tkwin, square->foregroundObj);
    Tcl_GetIntFromObj(NULL, square->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, square->reliefObj, &relief);

    Tk_Fill3DRectangle(tkwin, d, foreground,
	b.x, b.y, b.width, b.height, borderWidth, relief);

Changes to generic/ttk/ttkState.c.

1
2
3
4

5
6
7
8
9
10
11
1
2
3

4
5
6
7
8
9
10
11



-
+







/*
 * Tk widget state utilities.
 *
 * Copyright (c) 2003 Joe English.  Freely redistributable.
 * Copyright © 2003 Joe English.  Freely redistributable.
 *
 */

#include "tkInt.h"
#include "ttkTheme.h"

/*

Changes to generic/ttk/ttkStubInit.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





-
+







/*
 * This file is (mostly) automatically generated from ttk.decls.
 * It is compiled and linked in with the ttk package proper.
 */

#include "tk.h"
#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

Changes to generic/ttk/ttkStubLib.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








-
+







/*
 * We need to ensure that we use the tcl stub macros so that this file
 * contains no references to any of the tcl stub functions.
 */

#undef USE_TCL_STUBS
#define USE_TCL_STUBS

#include "tk.h"
#include "tkInt.h"

#define USE_TTK_STUBS 1
#include "ttkTheme.h"

MODULE_SCOPE const TtkStubs *ttkStubsPtr;
const TtkStubs *ttkStubsPtr = NULL;

30
31
32
33
34
35
36
37

38
39
40
41
42

43
44




45
46
47





48
49
50
51
52
53
54
30
31
32
33
34
35
36

37
38
39
40
41

42
43
44
45
46
47
48



49
50
51
52
53
54
55
56
57
58
59
60







-
+




-
+


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







 *
 */
MODULE_SCOPE const char *
TtkInitializeStubs(
    Tcl_Interp *interp, const char *version, int epoch, int revision)
{
    int exact = 0;
    const char *packageName = "Ttk";
    const char *packageName = "ttk";
    const char *errMsg = NULL;
    void *pkgClientData = NULL;
    const char *actualVersion = Tcl_PkgRequireEx(
	interp, packageName, version, exact, &pkgClientData);
    const TtkStubs *stubsPtr = (const TtkStubs *)pkgClientData;
    const TtkStubs *stubsPtr;

    if (!actualVersion) {
	packageName = "Ttk";
	actualVersion = Tcl_PkgRequireEx(
		interp, packageName, version, exact, &pkgClientData);
	if (!actualVersion) {
	return NULL;
    }

	    return NULL;
	}
    }

    stubsPtr = (const TtkStubs *)pkgClientData;
    if (!stubsPtr) {
	errMsg = "missing stub table pointer";
	goto error;
    }
    if (stubsPtr->epoch != epoch) {
	errMsg = "epoch number mismatch";
	goto error;

Changes to generic/ttk/ttkTagSet.c.

1
2
3
4

5
6
7
8
9
10
11
1
2
3

4
5
6
7
8
9
10
11



-
+







/*
 * Tag tables.  3/4-baked, work in progress.
 *
 * Copyright (C) 2005, Joe English.  Freely redistributable.
 * Copyright © 2005, Joe English.  Freely redistributable.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

/*------------------------------------------------------------------------

Changes to generic/ttk/ttkTheme.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





-
-
+
+







/*
 * ttkTheme.c --
 *
 *	This file implements the widget styles and themes support.
 *
 * Copyright (c) 2002 Frederic Bonnet
 * Copyright (c) 2003 Joe English
 * Copyright © 2002 Frederic Bonnet
 * Copyright © 2003 Joe English
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "ttkThemeInt.h"
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)
287
288
289
290
291
292
293
294

295
296
297
298



299
300

301
302
303
304
305
306
307
287
288
289
290
291
292
293

294




295
296
297
298

299
300
301
302
303
304
305
306







-
+
-
-
-
-
+
+
+

-
+







    ckfree(elementClass);
}

/*------------------------------------------------------------------------
 * +++ Themes.
 */

static int ThemeEnabled(Ttk_Theme theme, void *dummy)
static int ThemeEnabled(
{
    (void)theme;
    (void)dummy;

    TCL_UNUSED(Ttk_Theme),
    TCL_UNUSED(void *))
{
    /* Default ThemeEnabledProc -- always return true */
	return 1;
    return 1;
}

typedef struct Ttk_Theme_
{
    Ttk_Theme parentPtr;             	/* Parent theme. */
    Tcl_HashTable elementTable;	     	/* Map element names to class records */
    Tcl_HashTable styleTable;	     	/* Map style names to Styles */
386
387
388
389
390
391
392
393

394
395
396
397
398
399
400
401
402
403
404
405
406
407

408
409
410
411
412



413
414
415
416
417
418
419
420
421
422
423
424
425
385
386
387
388
389
390
391

392
393
394
395
396
397
398
399
400
401
402
403
404
405

406
407
408
409
410

411
412
413
414
415
416
417
418

419
420
421
422
423
424
425







-
+













-
+




-
+
+
+





-







typedef struct CleanupStruct {
    void *clientData;
    Ttk_CleanupProc *cleanupProc;
    struct CleanupStruct *next;
} Cleanup;

/*------------------------------------------------------------------------
 * +++ Master style package data structure.
 * +++ Style package data structure.
 */
typedef struct
{
    Tcl_Interp *interp;			/* Owner interp */
    Tcl_HashTable themeTable;		/* KEY: name; VALUE: Theme pointer */
    Tcl_HashTable factoryTable; 	/* KEY: name; VALUE: FactoryRec ptr */
    Theme *defaultTheme;		/* Default theme; global fallback*/
    Theme *currentTheme;		/* Currently-selected theme */
    Cleanup *cleanupList;		/* Cleanup records */
    Ttk_ResourceCache cache;		/* Resource cache */
    int themeChangePending;		/* scheduled ThemeChangedProc call? */
} StylePackageData;

static void ThemeChangedProc(ClientData);	/* Forward */
static void ThemeChangedProc(void *);	/* Forward */

/* Ttk_StylePkgFree --
 *	Cleanup procedure for StylePackageData.
 */
static void Ttk_StylePkgFree(ClientData clientData, Tcl_Interp *dummy)
static void Ttk_StylePkgFree(
    ClientData clientData,
    TCL_UNUSED(Tcl_Interp *))
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Tcl_HashSearch search;
    Tcl_HashEntry *entryPtr;
    Cleanup *cleanup;
    (void)dummy;

    /*
     * Cancel any pending ThemeChanged calls:
     */
    if (pkgPtr->themeChangePending) {
	Tcl_CancelIdleCall(ThemeChangedProc, pkgPtr);
    }
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
513
514
515
516
517
518
519



520
521
522
523
524
525
526







-
-
-







    StylePackageData *pkgPtr = (StylePackageData *)clientData;

    int code = Tcl_EvalEx(pkgPtr->interp, ThemeChangedScript, -1, TCL_EVAL_GLOBAL);
    if (code != TCL_OK) {
	Tcl_BackgroundException(pkgPtr->interp, code);
    }
    pkgPtr->themeChangePending = 0;
#ifdef MAC_OSX_TK
    XSync(NULL, False);
#endif
}

/*
 * ThemeChanged --
 * 	Schedule a call to ThemeChanged if one is not already pending.
 */
static void ThemeChanged(StylePackageData *pkgPtr)
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







-
+







 * LookupTheme --
 *	Retrieve a registered theme by name.  If not found,
 *	returns NULL and leaves an error message in interp's result.
 */

static Ttk_Theme LookupTheme(
    Tcl_Interp *interp,		/* where to leave error messages */
    StylePackageData *pkgPtr,	/* style package master record */
    StylePackageData *pkgPtr,	/* style package record */
    const char *name)		/* theme name */
{
    Tcl_HashEntry *entryPtr;

    entryPtr = Tcl_FindHashEntry(&pkgPtr->themeTable, name);
    if (!entryPtr) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
826
827
828
829
830
831
832
833

834
835
836
837
838
839
840
841
842
843
844
845
846
823
824
825
826
827
828
829

830
831
832
833
834
835

836
837
838
839
840
841
842







-
+





-







    return TCL_OK;
}

/* Ttk_CloneElement -- element factory procedure.
 * 	(style element create $name) "from" $theme ?$element?
 */
static int Ttk_CloneElement(
    Tcl_Interp *interp, void *dummy,
    Tcl_Interp *interp, TCL_UNUSED(void *),
    Ttk_Theme theme, const char *elementName,
    int objc, Tcl_Obj *const objv[])
{
    Ttk_Theme fromTheme;
    Ttk_ElementClass *fromElement;
    (void)dummy;

    if (objc <= 0 || objc > 2) {
	Tcl_WrongNumArgs(interp, 0, objv, "theme ?element?");
	return TCL_ERROR;
    }

    fromTheme = Ttk_GetTheme(interp, Tcl_GetString(objv[0]));
1178
1179
1180
1181
1182
1183
1184
1185

1186
1187
1188
1189
1190
1191
1192
1174
1175
1176
1177
1178
1179
1180

1181
1182
1183
1184
1185
1186
1187
1188







-
+







/* + style map $style ? -resource statemap ... ?
 *
 * 	Note that resource names are unconstrained; the Style
 * 	doesn't know what resources individual elements may use.
 */
static int
StyleMapCmd(
    ClientData clientData,		/* Master StylePackageData pointer */
    ClientData clientData,		/* StylePackageData pointer */
    Tcl_Interp *interp,			/* Current interpreter */
    int objc,				/* Number of arguments */
    Tcl_Obj *const objv[])		/* Argument objects */
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme theme = pkgPtr->currentTheme;
    const char *styleName;
1262
1263
1264
1265
1266
1267
1268
1269

1270
1271
1272

1273
1274
1275
1276
1277
1278
1279
1258
1259
1260
1261
1262
1263
1264

1265
1266
1267

1268
1269
1270
1271
1272
1273
1274
1275







-
+


-
+







	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;
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324

1325
1326
1327
1328
1329
1330
1331
1311
1312
1313
1314
1315
1316
1317



1318
1319
1320
1321
1322
1323
1324
1325







-
-
-
+








    if (objc < 4 || objc > 6) {
	Tcl_WrongNumArgs(interp, 2, objv, "style -option ?state? ?default?");
	return TCL_ERROR;
    }

    style = Ttk_GetStyle(theme, Tcl_GetString(objv[2]));
    if (!style) {
	return TCL_ERROR;
    }

    optionName = Tcl_GetString(objv[3]);

    if (objc >= 5) {
	Ttk_StateSpec stateSpec;
	/* @@@ SB: Ttk_GetStateFromObj(); 'offbits' spec is ignored */
	if (Ttk_GetStateSpecFromObj(interp, objv[4], &stateSpec) != TCL_OK) {
	    return TCL_ERROR;
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
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







-
+
+
+
+


-
-











-
+







    }
}

/* + style theme names --
 * 	Return list of registered themes.
 */
static int StyleThemeNamesCmd(
    ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
    ClientData clientData,
    Tcl_Interp *interp,
    TCL_UNUSED(int),
    TCL_UNUSED(Tcl_Obj *const *))
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    (void)objc;
    (void)objv;

    return TtkEnumerateHashTable(interp, &pkgPtr->themeTable);
}

/* + style theme settings $theme $script
 *
 * 	Temporarily sets the current theme to $themeName,
 * 	evaluates $script, then restores the old theme.
 */
static int
StyleThemeSettingsCmd(
    ClientData clientData,		/* Master StylePackageData pointer */
    ClientData clientData,		/* StylePackageData pointer */
    Tcl_Interp *interp,			/* Current interpreter */
    int objc,				/* Number of arguments */
    Tcl_Obj *const objv[])		/* Argument objects */
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme oldTheme = pkgPtr->currentTheme;
    Ttk_Theme newTheme;
1610
1611
1612
1613
1614
1615
1616

























1617
1618
1619
1620
1621
1622
1623

1624
1625
1626
1627
1628
1629
1630
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







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






-
+







	    return TCL_ERROR;
	}
	Ttk_RegisterLayoutTemplate(theme, layoutName, layoutTemplate);
	ThemeChanged(pkgPtr);
    }
    return TCL_OK;
}

/* + style theme styles ?$theme? --
 * 	Return list of styles available in $theme.
 *      Use the current theme if $theme is omitted.
 */
static int StyleThemeStylesCmd(
    TCL_UNUSED(ClientData), Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Ttk_Theme themePtr;

    if (objc < 3 || objc > 4) {
        Tcl_WrongNumArgs(interp, 3, objv, "?theme?");
        return TCL_ERROR;
    }

    if (objc == 3) {
        themePtr = Ttk_GetCurrentTheme(interp);
    } else {
        themePtr = Ttk_GetTheme(interp, Tcl_GetString(objv[3]));
    }
    if (!themePtr)
        return TCL_ERROR;

    return TtkEnumerateHashTable(interp, &themePtr->styleTable);
}

/* + style theme use $theme --
 *  	Sets the current theme to $theme
 */
static int
StyleThemeUseCmd(
    ClientData clientData,		/* Master StylePackageData pointer */
    ClientData clientData,		/* StylePackageData pointer */
    Tcl_Interp *interp,			/* Current interpreter */
    int objc,				/* Number of arguments */
    Tcl_Obj *const objv[])		/* Argument objects */
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme theme;

1650
1651
1652
1653
1654
1655
1656

1657
1658
1659
1660
1661
1662
1663
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684







+







 *	Implementation of the [style] command.
 */

static const Ttk_Ensemble StyleThemeEnsemble[] = {
    { "create", StyleThemeCreateCmd, 0 },
    { "names", StyleThemeNamesCmd, 0 },
    { "settings", StyleThemeSettingsCmd, 0 },
    { "styles", StyleThemeStylesCmd, 0 },
    { "use", StyleThemeUseCmd, 0 },
    { NULL, 0, 0 }
};

static const Ttk_Ensemble StyleElementEnsemble[] = {
    { "create", StyleElementCreateCmd, 0 },
    { "names", StyleElementNamesCmd, 0 },
1673
1674
1675
1676
1677
1678
1679
1680

1681
1682
1683
1684
1685
1686
1687
1694
1695
1696
1697
1698
1699
1700

1701
1702
1703
1704
1705
1706
1707
1708







-
+







    { "theme", 0, StyleThemeEnsemble },
    { "element", 0, StyleElementEnsemble },
    { NULL, 0, 0 }
};

static int
StyleObjCmd(
    ClientData clientData,		/* Master StylePackageData pointer */
    ClientData clientData,		/* StylePackageData pointer */
    Tcl_Interp *interp,			/* Current interpreter */
    int objc,				/* Number of arguments */
    Tcl_Obj *const objv[])		/* Argument objects */
{
    return Ttk_InvokeEnsemble(StyleEnsemble, 1, clientData,interp,objc,objv);
}

Changes to generic/ttk/ttkTrace.c.

22
23
24
25
26
27
28
29
30


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
22
23
24
25
26
27
28


29
30
31
32
33
34
35


36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61







-
-
+
+





-
-


















-
+







/*
 * Tcl_VarTraceProc for trace handles.
 */
static char *
VarTraceProc(
    ClientData clientData,	/* Widget record pointer */
    Tcl_Interp *interp, 	/* Interpreter containing variable. */
    const char *name1,		/* (unused) */
    const char *name2,		/* (unused) */
    TCL_UNUSED(const char *),	/* name1 */
    TCL_UNUSED(const char *),	/* name2 */
    int flags)			/* Information about what happened. */
{
    Ttk_TraceHandle *tracePtr = (Ttk_TraceHandle *)clientData;
    const char *name, *value;
    Tcl_Obj *valuePtr;
    (void)name1;
    (void)name2;

    if (Tcl_InterpDeleted(interp)) {
	return NULL;
    }

    name = Tcl_GetString(tracePtr->varnameObj);

    /*
     * If the variable is being unset, then re-establish the trace:
     */
    if (flags & TCL_TRACE_DESTROYED) {
	/*
	 * If a prior call to Ttk_UntraceVariable() left behind an
	 * indicator that we wanted this handler to be deleted (see below),
	 * cleanup the ClientData bits and exit.
	 */
	if (tracePtr->interp == NULL) {
	    Tcl_DecrRefCount(tracePtr->varnameObj);
	    ckfree((ClientData)tracePtr);
	    ckfree(tracePtr);
	    return NULL;
	}
	Tcl_TraceVar2(interp, name, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		VarTraceProc, clientData);
	tracePtr->callback(tracePtr->clientData, NULL);
	return NULL;
94
95
96
97
98
99
100
101

102
103
104
105
106
107
108
92
93
94
95
96
97
98

99
100
101
102
103
104
105
106







-
+







    h->varnameObj = Tcl_DuplicateObj(varnameObj);
    Tcl_IncrRefCount(h->varnameObj);
    h->clientData = clientData;
    h->callback = callback;

    status = Tcl_TraceVar2(interp, Tcl_GetString(varnameObj),
	    NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
	    VarTraceProc, (ClientData)h);
	    VarTraceProc, h);

    if (status != TCL_OK) {
	Tcl_DecrRefCount(h->varnameObj);
	ckfree(h);
	return NULL;
    }

135
136
137
138
139
140
141
142

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

158
159
160
161
162
163
164
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

155
156
157
158
159
160
161
162







-
+














-
+








	/*
	 * Search the traces on the variable to see if the one we are tasked
	 * with removing is present.
	 */
	while ((cd = Tcl_VarTraceInfo(h->interp, Tcl_GetString(h->varnameObj),
		TCL_GLOBAL_ONLY, VarTraceProc, cd)) != NULL) {
	    if (cd == (ClientData) h) {
	    if (cd == h) {
		break;
	    }
	}
	/*
	 * If the trace we wish to delete is not visible, Tcl_UntraceVar
	 * will do nothing, so don't try to call it.  Instead set an
	 * indicator in the Ttk_TraceHandle that we need to cleanup later.
	 */
	if (cd == NULL) {
	    h->interp = NULL;
	    return;
	}
	Tcl_UntraceVar2(h->interp, Tcl_GetString(h->varnameObj),
		NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		VarTraceProc, (ClientData)h);
		VarTraceProc, h);
	Tcl_DecrRefCount(h->varnameObj);
	ckfree(h);
    }
}

/*
 * Ttk_FireTrace --

Changes to generic/ttk/ttkTrack.c.

1
2

3
4
5
6
7
8
9
1

2
3
4
5
6
7
8
9

-
+







/*
 * Copyright (c) 2004, Joe English
 * Copyright © 2004, Joe English
 *
 * TtkTrackElementState() -- helper routine for widgets
 * like scrollbars in which individual elements may
 * be active or pressed instead of the widget as a whole.
 *
 * Usage:
 * 	TtkTrackElementState(&recordPtr->core);

Changes to generic/ttk/ttkTreeview.c.

1
2

3
4
5
6
7
8
9
1

2
3
4
5
6
7
8
9

-
+







/*
 * Copyright (c) 2004, Joe English
 * Copyright © 2004, Joe English
 *
 * ttk::treeview widget implementation.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
437
438
439
440
441
442
443
444

445
446
447

448
449
450

451
452
453
454

455
456
457
458

459
460
461
462
463
464
465
437
438
439
440
441
442
443

444
445
446

447
448
449

450
451
452
453

454
455
456
457

458
459
460
461
462
463
464
465







-
+


-
+


-
+



-
+



-
+







#define SHOW_CHANGED 		(USER_MASK<<3)

static const char *const SelectModeStrings[] = { "none", "browse", "extended", NULL };

static const Tk_OptionSpec TreeviewOptionSpecs[] = {
    {TK_OPTION_STRING, "-columns", "columns", "Columns",
	"", offsetof(Treeview,tree.columnsObj), TCL_INDEX_NONE,
	0,0,COLUMNS_CHANGED | GEOMETRY_CHANGED /*| READONLY_OPTION*/ },
	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 },
	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 },
	0, 0,SHOW_CHANGED | GEOMETRY_CHANGED },

    {TK_OPTION_STRING_TABLE, "-selectmode", "selectMode", "SelectMode",
	"extended", offsetof(Treeview,tree.selectModeObj), TCL_INDEX_NONE,
	0,(ClientData)SelectModeStrings,0 },
	0, (void *)SelectModeStrings, 0 },

    {TK_OPTION_PIXELS, "-height", "height", "Height",
	DEF_TREE_ROWS, offsetof(Treeview,tree.heightObj), TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED},
	0, 0,GEOMETRY_CHANGED},
    {TK_OPTION_STRING, "-padding", "padding", "Pad",
	NULL, offsetof(Treeview,tree.paddingObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },

    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	NULL, TCL_INDEX_NONE, offsetof(Treeview, tree.xscroll.scrollCmd),
	TK_OPTION_NULL_OK, 0, SCROLLCMD_CHANGED},
788
789
790
791
792
793
794
795
796


797
798
799
800
801
802
803
804
788
789
790
791
792
793
794


795
796

797
798
799
800
801
802
803







-
-
+
+
-







 * 	That is, don't bother changing column widths if the tree
 * 	is already scrolled or short.
 */
static int PickupSlack(Treeview *tv, int extra)
{
    int newSlack = tv->tree.slack + extra;

    if (   (newSlack < 0 && 0 <= tv->tree.slack)
	|| (newSlack > 0 && 0 >= tv->tree.slack))
    if ((newSlack < 0 && 0 <= tv->tree.slack)
	    || (newSlack > 0 && 0 >= tv->tree.slack)) {
    {
	tv->tree.slack = 0;
	return newSlack;
    } else {
	tv->tree.slack = newSlack;
	return 0;
    }
}
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106



1107
1108
1109
1110
1111
1112
1113
1114
1096
1097
1098
1099
1100
1101
1102



1103
1104
1105

1106
1107
1108
1109
1110
1111
1112







-
-
-
+
+
+
-







	if (TreeviewInitDisplayColumns(interp, tv) != TCL_OK)
	    return TCL_ERROR;
    }
    if (mask & SCROLLCMD_CHANGED) {
	TtkScrollbarUpdateRequired(tv->tree.xscrollHandle);
	TtkScrollbarUpdateRequired(tv->tree.yscrollHandle);
    }
    if (  (mask & SHOW_CHANGED)
	&& GetEnumSetFromObj(
		    interp,tv->tree.showObj,showStrings,&showFlags) != TCL_OK)
    if ((mask & SHOW_CHANGED)
	    && GetEnumSetFromObj(
		    interp,tv->tree.showObj,showStrings,&showFlags) != TCL_OK) {
    {
	return TCL_ERROR;
    }

    if (TtkCoreConfigure(interp, recordPtr, mask) != TCL_OK) {
	return TCL_ERROR;
    }

1776
1777
1778
1779
1780
1781
1782
1783

1784
1785
1786
1787
1788
1789
1790
1774
1775
1776
1777
1778
1779
1780

1781
1782
1783
1784
1785
1786
1787
1788







-
+







    if (tv->tree.showFlags & SHOW_TREE) {
	int indent = depth * tv->tree.indent;
	int colwidth = tv->tree.column0.width;
	Ttk_Box parcel = Ttk_MakeBox(
		x+indent, y, colwidth-indent, rowHeight);
	if (item->textObj) { displayItem.textObj = item->textObj; }
	if (item->imageObj) { displayItem.imageObj = item->imageObj; }
	/* ??? displayItem.anchorObj = 0; <<NOTE-ANCHOR>> */
        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);
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
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







-
+















-
+







 * 	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;
    int index = 0;
    TkSizeT index = 0;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "item");
	return TCL_ERROR;
    }
    item = FindItem(interp, tv, objv[2]);
    if (!item) {
	return TCL_ERROR;
    }

    while (item->prev) {
	++index;
	item = item->prev;
    }

    Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
    Tcl_SetObjResult(interp, TkNewIndexObj(index));
    return TCL_OK;
}

/* + $tv exists $itemid --
 * 	Test if the specified item id is present in the tree.
 */
static int TreeviewExistsCommand(
2197
2198
2199
2200
2201
2202
2203
2204
2205


2206
2207
2208
2209
2210
2211
2212
2213
2195
2196
2197
2198
2199
2200
2201


2202
2203

2204
2205
2206
2207
2208
2209
2210







-
-
+
+
-







    int dColumnNumber;
    char dcolbuf[16];
    int x, y, x1;
    (void)objc;

    /* ASSERT: objc == 4 */

    if (   Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK
	|| Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK
    if (Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK
	    || Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK) {
    ) {
	return TCL_ERROR;
    }

    dColumnNumber = IdentifyDisplayColumn(tv, x, &x1);
    if (dColumnNumber < 0) {
	goto done;
    }
2373
2374
2375
2376
2377
2378
2379
2380

2381
2382
2383
2384
2385
2386
2387
2370
2371
2372
2373
2374
2375
2376

2377
2378
2379
2380
2381
2382
2383
2384







-
+







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) {
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
2723
2724
2725
2726
2727
2728
2729

2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749


2750
2751

2752
2753
2754
2755
2756
2757
2758







-
+



















-
-
+
+
-







	    tv->tree.endPtr = 0;
	FreeItem(delq);
	delq = next;
    }

    ckfree(items);
    if (selItemDeleted) {
        TtkSendVirtualEvent(tv->core.tkwin, "TreeviewSelect");
        Tk_SendVirtualEvent(tv->core.tkwin, "TreeviewSelect", NULL);
    }
    TtkRedisplayWidget(&tv->core);
    return TCL_OK;
}

/* + $tv move $item $parent $index
 * 	Move $item to the specified $index in $parent's child list.
 */
static int TreeviewMoveCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *item, *parent;
    TreeItem *sibling;

    if (objc != 5) {
	Tcl_WrongNumArgs(interp, 2, objv, "item parent index");
	return TCL_ERROR;
    }
    if (   (item = FindItem(interp, tv, objv[2])) == 0
	|| (parent = FindItem(interp, tv, objv[3])) == 0)
    if ((item = FindItem(interp, tv, objv[2])) == 0
	    || (parent = FindItem(interp, tv, objv[3])) == 0) {
    {
	return TCL_ERROR;
    }

    /* Locate previous sibling based on $index:
     */
    if (!strcmp(Tcl_GetString(objv[4]), "end")) {
	sibling = EndPosition(tv, parent);
2875
2876
2877
2878
2879
2880
2881
2882
2883


2884
2885
2886
2887
2888
2889
2890
2891
2871
2872
2873
2874
2875
2876
2877


2878
2879

2880
2881
2882
2883
2884
2885
2886







-
-
+
+
-







    int newx;

    if (objc != 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "column xposition");
	return TCL_ERROR;
    }

    if (  (column = FindColumn(interp, tv, objv[2])) == 0
        || Tcl_GetIntFromObj(interp, objv[3], &newx) != TCL_OK)
    if ((column = FindColumn(interp, tv, objv[2])) == 0
	    || Tcl_GetIntFromObj(interp, objv[3], &newx) != TCL_OK) {
    {
	return TCL_ERROR;
    }

    for (;i < tv->tree.nDisplayColumns; ++i) {
	TreeColumn *c = tv->tree.displayColumns[i];
	int right = left + c->width;
	if (c == column) {
3007
3008
3009
3010
3011
3012
3013
3014

3015
3016
3017
3018
3019
3020
3021
3002
3003
3004
3005
3006
3007
3008

3009
3010
3011
3012
3013
3014
3015
3016







-
+







	    for (i=0; items[i]; ++i) {
		items[i]->state ^= TTK_STATE_SELECTED;
	    }
	    break;
    }

    ckfree(items);
    TtkSendVirtualEvent(tv->core.tkwin, "TreeviewSelect");
    Tk_SendVirtualEvent(tv->core.tkwin, "TreeviewSelect", NULL);
    TtkRedisplayWidget(&tv->core);

    return TCL_OK;
}

/*------------------------------------------------------------------------
 * +++ Widget commands -- tags and bindings.
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
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







-

+









+







    { "drag",   	TreeviewDragCommand,0 },
    { "drop",   	TreeviewDropCommand,0 },
    { "exists", 	TreeviewExistsCommand,0 },
    { "focus", 		TreeviewFocusCommand,0 },
    { "heading", 	TreeviewHeadingCommand,0 },
    { "identify",  	TreeviewIdentifyCommand,0 },
    { "index",  	TreeviewIndexCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "insert", 	TreeviewInsertCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "item", 		TreeviewItemCommand,0 },
    { "move", 		TreeviewMoveCommand,0 },
    { "next", 		TreeviewNextCommand,0 },
    { "parent", 	TreeviewParentCommand,0 },
    { "prev", 		TreeviewPrevCommand,0 },
    { "see", 		TreeviewSeeCommand,0 },
    { "selection" ,	TreeviewSelectionCommand,0 },
    { "set",  		TreeviewSetCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    { "tag",    	0,TreeviewTagCommands },
    { "xview",  	TreeviewXViewCommand,0 },
    { "yview",  	TreeviewYViewCommand,0 },
    { 0,0,0 }
};

/*------------------------------------------------------------------------
3347
3348
3349
3350
3351
3352
3353
3354
3355

3356
3357
3358
3359
3360
3361
3362
3343
3344
3345
3346
3347
3348
3349


3350
3351
3352
3353
3354
3355
3356
3357







-
-
+







	TTK_GROUP("Treeview.padding", TTK_FILL_BOTH,
	    TTK_NODE("Treeview.treearea", TTK_FILL_BOTH))))

TTK_LAYOUT("Item",
    TTK_GROUP("Treeitem.padding", TTK_FILL_BOTH,
	TTK_NODE("Treeitem.indicator", TTK_PACK_LEFT)
	TTK_NODE("Treeitem.image", TTK_PACK_LEFT)
	TTK_GROUP("Treeitem.focus", TTK_PACK_LEFT,
	    TTK_NODE("Treeitem.text", TTK_PACK_LEFT))))
	TTK_NODE("Treeitem.text", TTK_FILL_BOTH)))

TTK_LAYOUT("Cell",
    TTK_GROUP("Treedata.padding", TTK_FILL_BOTH,
	TTK_NODE("Treeitem.text", TTK_FILL_BOTH)))

TTK_LAYOUT("Heading",
    TTK_NODE("Treeheading.cell", TTK_FILL_BOTH)

Changes to generic/ttk/ttkWidget.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

-
+





-
+







/*
 * Copyright (c) 2003, Joe English
 * Copyright © 2003, Joe English
 *
 * Core widget utilities.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkThemeInt.h"
#include "ttkWidget.h"

#ifdef MAC_OSX_TK
#define TK_NO_DOUBLE_BUFFERING 1
#endif

/*------------------------------------------------------------------------
209
210
211
212
213
214
215
216

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

216
217
218
219
220
221
222
223







-
+







DestroyWidget(WidgetCore *corePtr)
{
    corePtr->flags |= WIDGET_DESTROYED;

    corePtr->widgetSpec->cleanupProc(corePtr);

    Tk_FreeConfigOptions(
	(ClientData)corePtr, corePtr->optionTable, corePtr->tkwin);
	    corePtr, corePtr->optionTable, corePtr->tkwin);

    if (corePtr->layout) {
	Ttk_FreeLayout(corePtr->layout);
    }

    if (corePtr->flags & REDISPLAY_PENDING) {
	Tcl_CancelIdleCall(DrawWidget, corePtr);
790
791
792
793
794
795
796




















797
798
799
800
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







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





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

/* $w style
 * 	Return the style currently applied to the widget.
 */

int TtkWidgetStyleCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    WidgetCore *corePtr = (WidgetCore *)recordPtr;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, "");
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, Tcl_NewStringObj(
            Ttk_StyleName(Ttk_LayoutStyle(corePtr->layout)), -1));

    return TCL_OK;
}

/*EOF*/

Changes to generic/ttk/ttkWidget.h.

85
86
87
88
89
90
91


92
93
94

95
96
97
98
99
100

101
102
103
104
105
106
107
85
86
87
88
89
90
91
92
93
94
95

96
97
98
99
100
101

102
103
104
105
106
107
108
109







+
+


-
+





-
+







MODULE_SCOPE void TtkWidgetDoLayout(void *recordPtr);
MODULE_SCOPE void TtkWidgetDisplay(void *recordPtr, Drawable);

MODULE_SCOPE int TtkCoreConfigure(Tcl_Interp*, void *, int mask);

/* Common widget commands:
 */
MODULE_SCOPE int TtkWidgetCgetCommand(
	void *,Tcl_Interp *, int, Tcl_Obj*const[]);
MODULE_SCOPE int TtkWidgetConfigureCommand(
	void *,Tcl_Interp *, int, Tcl_Obj*const[]);
MODULE_SCOPE int TtkWidgetCgetCommand(
MODULE_SCOPE int TtkWidgetIdentifyCommand(
	void *,Tcl_Interp *, int, Tcl_Obj*const[]);
MODULE_SCOPE int TtkWidgetInstateCommand(
	void *,Tcl_Interp *, int, Tcl_Obj*const[]);
MODULE_SCOPE int TtkWidgetStateCommand(
	void *,Tcl_Interp *, int, Tcl_Obj*const[]);
MODULE_SCOPE int TtkWidgetIdentifyCommand(
MODULE_SCOPE int TtkWidgetStyleCommand(
	void *,Tcl_Interp *, int, Tcl_Obj*const[]);

/* Widget constructor:
 */
MODULE_SCOPE int TtkWidgetConstructorObjCmd(
	ClientData, Tcl_Interp*, int, Tcl_Obj*const[]);

160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
162
163
164
165
166
167
168





169
170
171
172
173
174
175







-
-
-
-
-







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

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 (c) 1998-2000 by Ajuba Solutions.
# Copyright (c) 2007 by ActiveState Software Inc.
# Copyright (c) 2007 Daniel A. Steffen <[email protected]>
# Copyright (c) 2009 Pat Thoyts <[email protected]>
# Copyright © 1998-2000 Ajuba Solutions.
# Copyright © 2007 ActiveState Software Inc.
# Copyright © 2007 Daniel A. Steffen <[email protected]>
# Copyright © 2009 Pat Thoyts <[email protected]>

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]
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60







-
+








-
+







    set button $code
}

proc ::tk::dialog::error::Details {} {
    set w .bgerrorDialog
    set caption [option get $w.function text {}]
    set command [option get $w.function command {}]
    if { ($caption eq "") || ($command eq "") } {
    if {($caption eq "") || ($command eq "")} {
	grid forget $w.function
    }
    lappend command [$w.top.info.text get 1.0 end-1c]
    $w.function configure -text $caption -command $command
    grid $w.top.info - -sticky nsew -padx 3m -pady 3m
}

proc ::tk::dialog::error::SaveToLog {text} {
    if { $::tcl_platform(platform) eq "windows" } {
    if {$::tcl_platform(platform) eq "windows"} {
	set allFiles *.*
    } else {
	set allFiles *
    }
    set types [list \
	    [list [mc "Log Files"] .log]      \
	    [list [mc "Text Files"] .txt]     \
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







-
-
+
+


-
+







    # Truncate the message if it is too wide (>maxLine characters) or
    # too tall (>4 lines).  Truncation occurs at the first point at
    # which one of those conditions is met.
    set displayedErr ""
    set lines 0
    set maxLine 45
    foreach line [split $err \n] {
	if { [string length $line] > $maxLine } {
	    append displayedErr "[string range $line 0 [expr {$maxLine-3}]]..."
	if {[string length $line] > $maxLine} {
	    append displayedErr "[string range $line 0 $maxLine-3]..."
	    break
	}
	if { $lines > 4 } {
	if {$lines > 4} {
	    append displayedErr "..."
	    break
	} else {
	    append displayedErr "${line}\n"
	}
	incr lines
    }
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







-
+







    }

    ttk::scrollbar $W.scroll -command [list $W.text yview]
    pack $W.scroll -side right -fill y
    pack $W.text -side left -expand yes -fill both
    $W.text insert 0.0 "$err\n$info"
    $W.text mark set insert 0.0
    bind $W.text <Button-1> { focus %W }
    bind $W.text <Button-1> {focus %W}
    $W.text configure -state disabled

    # 2. Fill the top part with bitmap and message

    # Max-width of message is the width of the screen...
    set wrapwidth [winfo screenwidth $dlg]
    # ...minus the width of the icon, padding and a fudge factor for

Changes to library/button.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






-
-
-
+
+
+







# button.tcl --
#
# This file defines the default bindings for Tk label, button,
# checkbutton, and radiobutton widgets and provides procedures
# that help in implementing those bindings.
#
# Copyright (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 2002 ActiveState Corporation.
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 2002 ActiveState Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

#-------------------------------------------------------------------------
# The code below creates the default class bindings for buttons.
37
38
39
40
41
42
43
44

45
46
47

48
49
50
51
52
53
54
37
38
39
40
41
42
43

44
45
46

47
48
49
50
51
52
53
54







-
+


-
+







	tk::ButtonUp %W
    }
    bind Checkbutton <Leave> {
	tk::ButtonLeave %W
    }
}
if {"win32" eq [tk windowingsystem]} {
    bind Checkbutton <equal> {
    bind Checkbutton <=> {
	tk::CheckRadioInvoke %W select
    }
    bind Checkbutton <plus> {
    bind Checkbutton <+> {
	tk::CheckRadioInvoke %W select
    }
    bind Checkbutton <minus> {
	tk::CheckRadioInvoke %W deselect
    }
    bind Checkbutton <Button-1> {
	tk::CheckRadioDown %W

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 (c) 1998-2000 by Scriptics Corporation.
# Copyright © 1998-2000 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

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 (c) 1996 Sun Microsystems, Inc.
# Copyright © 1996 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# ToDo:
#
#	(1): Find out how many free colors are left in the colormap and

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 (c) 1996 Sun Microsystems, Inc.
# Copyright © 1996 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# tclParseConfigSpec --
#
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 (c) 1995-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 Ajuba Solutions.
# Copyright (c) 2007-2008 Daniel A. Steffen <[email protected]>
# Copyright © 1995-1997 Sun Microsystems, Inc.
# Copyright © 1998-2000 Ajuba Solutions.
# Copyright © 2007-2008 Daniel A. Steffen <[email protected]>
#
# 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

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







-
+







    set families [font families]
    switch -exact -- [tk windowingsystem] {
        aqua { set preferred {Monaco 10} }
        win32 { set preferred {ProFontWindows 8 Consolas 8} }
        default { set preferred {} }
    }
    foreach {family size} $preferred {
        if {[lsearch -exact $families $family] != -1} {
        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 {
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 $filename]
    	set cmd [list source -encoding utf-8 $filename]
	if {[catch {consoleinterp eval $cmd} result]} {
	    ConsoleOutput stderr "$result\n"
	}
    }
}

# ::tk::ConsoleInvoke --
450
451
452
453
454
455
456
457

458


459
460
461
462
463
464
465
466
467
468
469
470
471
472


473
474
475
476
477
478
479
480
450
451
452
453
454
455
456

457
458
459
460
461
462
463
464










465
466

467
468
469
470
471
472
473







-
+

+
+




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







	<<Console_Eval>>		<KP_Enter>

	<<Console_Clear>>		<Control-l>
	<<Console_KillLine>>		<Control-k>
	<<Console_Transpose>>		<Control-t>
	<<Console_ClearLine>>		<Control-u>
	<<Console_SaveCommand>>		<Control-z>
	<<Console_FontSizeIncr>>	<Control-plus>
	<<Console_FontSizeIncr>>	<Control-+>
	<<Console_FontSizeDecr>>	<Control-minus>
	<<Console_FontSizeIncr>>	<Command-+>
	<<Console_FontSizeDecr>>	<Command-minus>
    } {
	event add $ev $key
	bind Console $key {}
    }
    if {[tk windowingsystem] eq "aqua"} {
	foreach {ev key} {
	    <<Console_FontSizeIncr>>	<Command-plus>
	    <<Console_FontSizeDecr>>	<Command-minus>
	} {
	    event add $ev $key
	    bind Console $key {}
	}
	if {$::tk::console::useFontchooser} {
	    bind Console <Command-t> [list ::tk::console::FontchooserToggle]
    if {$::tk::console::useFontchooser} {
	bind Console <Command-t> [list ::tk::console::FontchooserToggle]
	}
    }
    bind Console <<Console_Expand>> {
	if {[%W compare insert > promptEnd]} {
	    ::tk::console::Expand %W
	}
    }
    bind Console <<Console_ExpandFile>> {
588
589
590
591
592
593
594
595

596
597
598
599


600
601
602
603
604
605
606
607
581
582
583
584
585
586
587

588
589



590
591

592
593
594
595
596
597
598







-
+

-
-
-
+
+
-







	catch {tk::ConsoleInsert %W [::tk::GetSelection %W PRIMARY]}
    }
    bind Console <Key> {
	tk::ConsoleInsert %W %A
    }
    bind Console <F9> {
	eval destroy [winfo child .]
	source [file join $tk_library console.tcl]
	source -encoding utf-8 [file join $tk_library console.tcl]
    }
    if {[tk windowingsystem] eq "aqua"} {
	bind Console <Command-q> {
	    exit
    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]
736
737
738
739
740
741
742
743

744
745

746
747
748
749
750
751
752
727
728
729
730
731
732
733

734
735

736
737
738
739
740
741
742
743







-
+

-
+







	tk fontchooser hide
    } else {
	tk fontchooser show
    }
}
proc ::tk::console::FontchooserVisibility {index} {
    if {[tk fontchooser configure -visible]} {
	.menubar.edit entryconfigure $index -label [msgcat::mc "Hide Fonts"]
	.menubar.edit entryconfigure $index -label [::tk::msgcat::mc "Hide Fonts"]
    } else {
	.menubar.edit entryconfigure $index -label [msgcat::mc "Show Fonts"]
	.menubar.edit entryconfigure $index -label [::tk::msgcat::mc "Show Fonts"]
    }
}
proc ::tk::console::FontchooserFocus {w isFocusIn} {
    if {$isFocusIn} {
	tk fontchooser configure -parent $w -font TkConsoleFont \
		-command [namespace code [list FontchooserApply]]
    } else {

Changes to library/demos/bind.tcl.

63
64
65
66
67
68
69
70
71
72
73
74
75






76
77
78
63
64
65
66
67
68
69






70
71
72
73
74
75
76
77
78







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



# Create bindings for tags.

foreach tag {d1 d2 d3 d4 d5 d6} {
    $w.text tag bind $tag <Enter> "$w.text tag configure $tag $bold"
    $w.text tag bind $tag <Leave> "$w.text tag configure $tag $normal"
}
# Main widget program sets variable tk_demoDirectory
$w.text tag bind d1 <Button-1> {source [file join $tk_demoDirectory items.tcl]}
$w.text tag bind d2 <Button-1> {source [file join $tk_demoDirectory plot.tcl]}
$w.text tag bind d3 <Button-1> {source [file join $tk_demoDirectory ctext.tcl]}
$w.text tag bind d4 <Button-1> {source [file join $tk_demoDirectory arrow.tcl]}
$w.text tag bind d5 <Button-1> {source [file join $tk_demoDirectory ruler.tcl]}
$w.text tag bind d6 <Button-1> {source [file join $tk_demoDirectory cscroll.tcl]}
$w.text tag bind d1 <Button-1> {source -encoding utf-8 [file join $tk_demoDirectory items.tcl]}
$w.text tag bind d2 <Button-1> {source -encoding utf-8 [file join $tk_demoDirectory plot.tcl]}
$w.text tag bind d3 <Button-1> {source -encoding utf-8 [file join $tk_demoDirectory ctext.tcl]}
$w.text tag bind d4 <Button-1> {source -encoding utf-8 [file join $tk_demoDirectory arrow.tcl]}
$w.text tag bind d5 <Button-1> {source -encoding utf-8 [file join $tk_demoDirectory ruler.tcl]}
$w.text tag bind d6 <Button-1> {source -encoding utf-8 [file join $tk_demoDirectory cscroll.tcl]}

$w.text mark set insert 0.0
$w.text configure -state disabled

Changes to library/demos/cscroll.tcl.

52
53
54
55
56
57
58

59
60


61
62
63

64
65
66

67
68
69

70
71
72

73












74
75


76
77
78
79
80
81



82
83

84
85

86
87
88
89







90

91
92

93
94
95
96
97

98
99
100
101
102
103
104
52
53
54
55
56
57
58
59


60
61

62

63
64
65

66
67
68

69
70
71

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


86
87






88
89
90
91

92
93

94
95
96
97
98
99
100
101
102
103
104
105

106
107

108
109
110
111
112

113
114
115
116
117
118
119
120







+
-
-
+
+
-

-
+


-
+


-
+


-
+

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

-
+

-
+




+
+
+
+
+
+
+
-
+

-
+




-
+







	    -anchor center -tags text
    }
}

$c bind all <Enter> "scrollEnter $c"
$c bind all <Leave> "scrollLeave $c"
$c bind all <Button-1> "scrollButton $c"
if {([tk windowingsystem] eq "aqua") && ![package vsatisfies [package provide Tk] 8.7-]} {
bind $c <Button-2> "$c scan mark %x %y"
bind $c <B2-Motion> "$c scan dragto %x %y"
    bind $c <Button-3> "$c scan mark %x %y"
    bind $c <B3-Motion> "$c scan dragto %x %y"
if {[tk windowingsystem] eq "aqua"} {
    bind $c <MouseWheel> {
	%W yview scroll [expr {-(%D)}] units
	%W yview scroll [expr {-%D}] units
    }
    bind $c <Option-MouseWheel> {
	%W yview scroll [expr {-10 * (%D)}] units
	%W yview scroll [expr {-10*%D}] units
    }
    bind $c <Shift-MouseWheel> {
	%W xview scroll [expr {-(%D)}] units
	%W xview scroll [expr {-%D}] units
    }
    bind $c <Shift-Option-MouseWheel> {
	%W xview scroll [expr {-10 * (%D)}] units
	%W xview scroll [expr {-10*%D}] units
    }
} else {
    bind $c <Button-2> "$c scan mark %x %y"
    bind $c <B2-Motion> "$c scan dragto %x %y"
    # We must make sure that positive and negative movements are rounded
    # equally to integers, avoiding the problem that
    #     (int)1/-30 = -1,
    # but
    #     (int)-1/-30 = 0
    # The following code ensure equal +/- behaviour.
    bind $c <MouseWheel> {
	if {%D >= 0} {
	    %W yview scroll [expr {%D/-30}] units
} else {
    # We must make sure that positive and negative movements are rounded
	} else {
	    %W yview scroll [expr {(%D-29)/-30}] units
    # equally to integers, avoiding the problem that
    #     (int)1/30 = 0,
    # but
    #     (int)-1/30 = -1
    # The following code ensure equal +/- behaviour.
    bind $c <MouseWheel> {
	}
    }
    bind $c <Option-MouseWheel> {
	if {%D >= 0} {
	    %W yview scroll [expr {-%D/30}] units
	    %W yview scroll [expr {%D/-3}] units
	} else {
	    %W yview scroll [expr {(29-%D)/30}] units
	    %W yview scroll [expr {(%D-2)/-3}] units
	}
    }
    bind $c <Shift-MouseWheel> {
	if {%D >= 0} {
	    %W xview scroll [expr {%D/-30}] units
	} else {
	    %W xview scroll [expr {(%D-29)/-30}] units
	}
    }
    bind $c <Shift-Option-MouseWheel> {
	if {%D >= 0} {
	    %W xview scroll [expr {-%D/30}] units
	    %W xview scroll [expr {%D/-3}] units
	} else {
	    %W xview scroll [expr {(29-%D)/30}] units
	    %W xview scroll [expr {(%D-2)/-3}] units
	}
    }
}

if {[tk windowingsystem] eq "x11"} {
if {[tk windowingsystem] eq "x11" && ![package vsatisfies [package provide Tk] 8.7-]} {
    # Support for mousewheels on Linux/Unix commonly comes through mapping
    # the wheel to the extended buttons.  If you have a mousewheel, find
    # Linux configuration info at:
    #	http://linuxreviews.org/howtos/xfree/mouse/
    bind $c <Button-4> {
	if {!$tk_strictMotif} {
	    %W yview scroll -5 units
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
130
131
132
133
134
135
136












137
138
139
140
141
142
143







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







	    %W yview scroll 5 units
	}
    }
    bind $c <Shift-Button-5> {
	if {!$tk_strictMotif} {
	    %W xview scroll 5 units
	}
    }
    if {[package vsatisfies [package provide Tk] 8.7]} {
	bind $c <Button-6> {
	    if {!$tk_strictMotif} {
		%W xview scroll -5 units
	    }
	}
	bind $c <Button-7> {
	    if {!$tk_strictMotif} {
		%W xview scroll 5 units
	    }
	}
    }
}


proc scrollEnter canvas {
    global oldFill
    set id [$canvas find withtag current]

Changes to library/demos/ctext.tcl.

46
47
48
49
50
51
52



53


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

56
57
58
59
60
61
62
63
64







+
+
+
-
+
+







$c bind text <Shift-Button-1> "$c select adjust current @%x,%y"
$c bind text <Shift-B1-Motion> "textB1Move $c %x %y"
$c bind text <Key> "textInsert $c %A"
$c bind text <Return> "textInsert $c \\n"
$c bind text <Control-h> "textBs $c"
$c bind text <BackSpace> "textBs $c"
$c bind text <Delete> "textDel $c"
if {[tk windowingsystem] eq "aqua" && ![package vsatisfies [package provide Tk] 8.7-]} {
    $c bind text <Button-3> "textPaste $c @%x,%y"
} else {
$c bind text <Button-2> "textPaste $c @%x,%y"
    $c bind text <Button-2> "textPaste $c @%x,%y"
}

# Next, create some items that allow the text's anchor position
# to be edited.

proc mkTextConfigBox {w x y option value color} {
    set item [$w create rect $x $y [expr {$x+30}] [expr {$y+30}] \
	    -outline black -fill $color -width 1]

Changes to library/demos/dialog1.tcl.

1
2
3
4
5
6
7
8




9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24


25
1
2
3
4




5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22


23
24
25




-
-
-
-
+
+
+
+





-
+








-
-
+
+

# dialog1.tcl --
#
# This demonstration script creates a dialog box with a local grab.

interp create slave
load {} Tk slave
slave eval {
    wm title . slave
interp create child
load {} Tk child
child eval {
    wm title . child
    wm geometry . +700+30
    pack [text .t -width 30 -height 10]
}

after idle {.dialog1.msg configure -wraplength 4i}
set i [tk_dialog .dialog1 "Dialog with local grab" {This is a modal dialog box.  It uses Tk's "grab" command to create a "local grab" on the dialog box.  The grab prevents any mouse or keyboard events from getting to any other windows in the application until you have answered the dialog by invoking one of the buttons below.  However, you can still interact with other applications.  For example, you should be able to edit text in the window named "slave" which was created by a slave interpreter.} \
set i [tk_dialog .dialog1 "Dialog with local grab" {This is a modal dialog box.  It uses Tk's "grab" command to create a "local grab" on the dialog box.  The grab prevents any mouse or keyboard events from getting to any other windows in the application until you have answered the dialog by invoking one of the buttons below.  However, you can still interact with other applications.  For example, you should be able to edit text in the window named "child" which was created by a child interpreter.} \
info 0 OK Cancel {Show Code}]

switch $i {
    0 {puts "You pressed OK"}
    1 {puts "You pressed Cancel"}
    2 {showCode .dialog1}
}

if {[interp exists slave]} {
    interp delete slave
if {[interp exists child]} {
    interp delete child
}

Changes to library/demos/entry3.tcl.

60
61
62
63
64
65
66
67

68
69
70
71
72
73

74
75
76
77
78
79
80
60
61
62
63
64
65
66

67
68
69
70
71
72

73
74
75
76
77
78
79
80







-
+





-
+







	after 200 [list focusAndFlash $W $fg $bg [expr {$count-1}]]
    }
}

labelframe $w.l1 -text "Integer Entry"
# Alternatively try using {string is digit} for arbitrary length numbers,
# and not just 32-bit ones.
entry $w.l1.e -validate focus -vcmd {string is integer %P}
entry $w.l1.e -validate focus -validatecommand {string is integer %P}
$w.l1.e configure -invalidcommand \
	"focusAndFlash %W [$w.l1.e cget -fg] [$w.l1.e cget -bg]"
pack $w.l1.e -fill x -expand 1 -padx 1m -pady 1m

labelframe $w.l2 -text "Length-Constrained Entry"
entry $w.l2.e -validate key -invcmd bell -vcmd {expr {[string length %P]<10}}
entry $w.l2.e -validate key -invcmd bell -validatecommand {expr {[string length %P]<10}}
pack $w.l2.e -fill x -expand 1 -padx 1m -pady 1m

### PHONE NUMBER ENTRY ###
# Note that the source to this is quite a bit longer as the behaviour
# demonstrated is a lot more ambitious than with the others.

# Initial content for the third entry widget
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







-
+







# vmode - The widget's validation mode
# idx -	  The index where replacement is to occur
# char -  The character (or string, though that will always be
#	  refused) to be overwritten at that point.

proc validatePhoneChange {W vmode idx char} {
    global phoneNumberMap entry3content
    if {$idx == -1} {return 1}
    if {$idx < 0} {return 1}
    after idle [list $W configure -validate $vmode -invcmd bell]
    if {
	!($idx<3 || $idx==6 || $idx==7 || $idx==11 || $idx>15) &&
	[string match {[0-9A-Za-z]} $char]
    } then {
	$W delete $idx
	$W insert $idx [string map $phoneNumberMap $char]
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172
173
174
175
176
177

178
179
180
181
182
183
184
185
157
158
159
160
161
162
163

164
165
166
167
168
169
170
171
172
173
174
175
176

177
178
179
180
181
182
183
184
185







-
+












-
+








	bell
	return -code break
    }
}

labelframe $w.l3 -text "US Phone-Number Entry"
entry $w.l3.e -validate key  -invcmd bell  -textvariable entry3content \
	-vcmd {validatePhoneChange %W %v %i %S}
	-validatecommand {validatePhoneChange %W %v %i %S}
# Click to focus goes to the first editable character...
bind $w.l3.e <FocusIn> {
    if {"%d" ne "NotifyAncestor"} {
	%W icursor 3
	after idle {%W selection clear}
    }
}
bind $w.l3.e <<PrevChar>> {phoneSkipLeft  %W}
bind $w.l3.e <<NextChar>> {phoneSkipRight %W}
pack $w.l3.e -fill x -expand 1 -padx 1m -pady 1m

labelframe $w.l4 -text "Password Entry"
entry $w.l4.e -validate key -show "*" -vcmd {expr {[string length %P]<=8}}
entry $w.l4.e -validate key -show "*" -validatecommand {expr {[string length %P]<=8}}
pack $w.l4.e -fill x -expand 1 -padx 1m -pady 1m

lower [frame $w.mid]
grid $w.l1 $w.l2 -in $w.mid -padx 3m -pady 1m -sticky ew
grid $w.l3 $w.l4 -in $w.mid -padx 3m -pady 1m -sticky ew
grid columnconfigure $w.mid {0 1} -uniform 1
pack $w.msg -side top
pack $w.mid -fill both -expand 1

Changes to library/demos/floor.tcl.

1355
1356
1357
1358
1359
1360
1361




1362
1363



1364
1365
1366
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365


1366
1367
1368
1369
1370
1371







+
+
+
+
-
-
+
+
+



# Set up event bindings for canvas:

$c bind floor1 <Button-1> "floorDisplay $c 1"
$c bind floor2 <Button-1> "floorDisplay $c 2"
$c bind floor3 <Button-1> "floorDisplay $c 3"
$c bind room <Enter> "newRoom $c"
$c bind room <Leave> {set currentRoom ""}
if {[tk windowingsystem] eq "aqua" && ![package vsatisfies [package provide Tk] 8.7-]} {
    bind $c <Button-3> "$c scan mark %x %y"
    bind $c <B3-Motion> "$c scan dragto %x %y"
} else {
bind $c <Button-2> "$c scan mark %x %y"
bind $c <B2-Motion> "$c scan dragto %x %y"
    bind $c <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"

Changes to library/demos/fontchoose.tcl.

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69


51
52
53
54
55
56
57




58
59
60
61
62
63
64
65
66
67







-
-
-
-








+
+

ttk::button $f.font -text "Set font ..." -command [list SelectFont $w]

grid $f.msg $f.vs -sticky news
grid $f.font -    -sticky e
grid columnconfigure $f 0 -weight 1
grid rowconfigure $f 0 -weight 1
bind $w <Visibility> {
    bind %W <Visibility> {}
    grid propagate %W.f 0
}

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]

grid $f -sticky news
grid $btns -sticky ew
grid columnconfigure $w 0 -weight 1
grid rowconfigure $w 0 -weight 1
update idletasks
grid propagate $f 0

Changes to library/demos/goldberg.tcl.

109
110
111
112
113
114
115
116

117
118

119
120
121
122
123
124
125
109
110
111
112
113
114
115

116
117

118
119
120
121
122
123
124
125







-
+

-
+







    bind $w.c <Destroy> {
	after cancel $animationCallbacks(goldberg)
	unset animationCallbacks(goldberg)
    }
    DoCtrlFrame $w
    DoDetailFrame $w
    if {[tk windowingsystem] ne "aqua"} {
	ttk::button $w.show -text "\u00bb" -command [list ShowCtrl $w] -width 2
	ttk::button $w.show -text "»" -command [list ShowCtrl $w] -width 2
    } else {
	button $w.show -text "\u00bb" -command [list ShowCtrl $w] -width 2 -highlightbackground $C(bg)
	button $w.show -text "»" -command [list ShowCtrl $w] -width 2 -highlightbackground $C(bg)
    }
    place $w.show -in $w.c -relx 1 -rely 0 -anchor ne
    update
}

proc DoCtrlFrame {w} {
    global S
200
201
202
203
204
205
206
207

208
209
210

211
212
213
214
215
216
217
200
201
202
203
204
205
206

207
208
209

210
211
212
213
214
215
216
217







-
+


-
+







    grid columnconfigure $w2 1 -weight 1
}

# Map or unmap the ctrl window
proc ShowCtrl {w} {
    if {[winfo ismapped $w.ctrl]} {
	pack forget $w.ctrl
	$w.show config -text "\u00bb"
	$w.show config -text "»"
    } else {
	pack $w.ctrl -side right -fill both -ipady 5
	$w.show config -text "\u00ab"
	$w.show config -text "»"
    }
}

proc DrawAll {w} {
    ResetStep
    $w.c delete all
    for {set i 0} {1} {incr i} {

Changes to library/demos/items.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







-
+







catch {destroy $w}
toplevel $w
wm title $w "Canvas Item Demonstration"
wm iconname $w "Items"
positionWindow $w
set c $w.frame.c

label $w.msg -font $font -wraplength 5i -justify left -text "This window contains a canvas widget with examples of the various kinds of items supported by canvases.  The following operations are supported:\n  Button-1 drag:\tmoves item under pointer.\n  Button-2 drag:\trepositions view.\n  Button-3 drag:\tstrokes out area.\n  Ctrl+f:\t\tprints items under area."
label $w.msg -font $font -wraplength 5i -justify left -text "This window contains a canvas widget with examples of the various kinds of items supported by canvases.  The following operations are supported:\n  Left-Button drag:\tmoves item under pointer.\n  Middle-Button drag:\trepositions view.\n  Right-Button drag:\tstrokes out area.\n  Ctrl+f:\t\tprints items under area."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.frame
169
170
171
172
173
174
175






176
177
178
179





180
181
182
183
184
185
186
169
170
171
172
173
174
175
176
177
178
179
180
181




182
183
184
185
186
187
188
189
190
191
192
193







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







$c create text 21c 20.9c -text Entry: -anchor sw
$c create text 28.5c 17.4c -text Scale: -anchor s

# Set up event bindings for canvas:

$c bind item <Enter> "itemEnter $c"
$c bind item <Leave> "itemLeave $c"
if {[tk windowingsystem] eq "aqua" && ![package vsatisfies [package provide Tk] 8.7-]} {
    bind $c <Button-2> "itemMark $c %x %y"
    bind $c <B2-Motion> "itemStroke $c %x %y"
    bind $c <Button-3> "$c scan mark %x %y"
    bind $c <B3-Motion> "$c scan dragto %x %y"
} else {
bind $c <Button-2> "$c scan mark %x %y"
bind $c <B2-Motion> "$c scan dragto %x %y"
bind $c <Button-3> "itemMark $c %x %y"
bind $c <B3-Motion> "itemStroke $c %x %y"
    bind $c <Button-2> "$c scan mark %x %y"
    bind $c <B2-Motion> "$c scan dragto %x %y"
    bind $c <Button-3> "itemMark $c %x %y"
    bind $c <B3-Motion> "itemStroke $c %x %y"
}
bind $c <<NextChar>> "itemsUnderArea $c"
bind $c <Button-1> "itemStartDrag $c %x %y"
bind $c <B1-Motion> "itemDrag $c %x %y"

# Utility procedures for highlighting the item under the pointer:

proc itemEnter {c} {
246
247
248
249
250
251
252
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
272
273
274







-
+






-
+







}

proc itemsUnderArea {c} {
    global areaX1 areaY1 areaX2 areaY2
    set area [$c find withtag area]
    set items ""
    foreach i [$c find enclosed $areaX1 $areaY1 $areaX2 $areaY2] {
	if {[lsearch [$c gettags $i] item] != -1} {
	if {[lsearch [$c gettags $i] item] >= 0} {
	    lappend items $i
	}
    }
    puts stdout "Items enclosed by area: $items"
    set items ""
    foreach i [$c find overlapping $areaX1 $areaY1 $areaX2 $areaY2] {
	if {[lsearch [$c gettags $i] item] != -1} {
	if {[lsearch [$c gettags $i] item] >= 0} {
	    lappend items $i
	}
    }
    puts stdout "Items overlapping area: $items"
}

set areaX1 0

Changes to library/demos/ixset.

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







-
+







    global mouseacc ;	set mouseacc	"3/1"
    global mousethr ;	set mousethr	4
    global screenbla ;	set screenbla	"blank"
    global screentim ;	set screentim	600
    global screencyc ;	set screencyc	600

    set xfd [open "|xset q" r]
    while {[gets $xfd line] > -1} {
    while {[gets $xfd line] >= 0} {
	switch -- [lindex $line 0] {
	    auto {
		set rpt [lindex $line 1]
		if {$rpt eq "repeat:"} {
		    set kbdrep [lindex $line 2]
		    set kbdcli [lindex $line 6]
		}

Changes to library/demos/knightstour.tcl.

1

2
3
4
5
6
7
8

1
2
3
4
5
6
7
8
-
+







# Copyright (C) 2008 Pat Thoyts <[email protected]>
# Copyright © 2008 Pat Thoyts <[email protected]>
#
#	Calculate a Knight's tour of a chessboard.
#
#	This uses Warnsdorff's rule to calculate the next square each
#	time. This specifies that the next square should be the one that
#	has the least number of available moves.
#
17
18
19
20
21
22
23
24

25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44

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

59
60
61
62
63
64
65
17
18
19
20
21
22
23

24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43

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

58
59
60
61
62
63
64
65







-
+







-
+











-
+













-
+







#	If the call to the Edgemost function is commented out you can see
#	this occur.
#
#	You can drag the knight to a specific square to start if you wish.
#	If you let it repeat then it will choose random start positions
#	for each new tour.

package require Tk 8.5
package require Tk

# Return a list of accessible squares from a given square
proc ValidMoves {square} {
    set moves {}
    foreach pair {{-1 -2} {-2 -1} {-2 1} {-1 2} {1 2} {2 1} {2 -1} {1 -2}} {
        set col [expr {($square % 8) + [lindex $pair 0]}]
        set row [expr {($square / 8) + [lindex $pair 1]}]
        if {$row > -1 && $row < 8 && $col > -1 && $col < 8} {
        if {$row >= 0 && $row < 8 && $col >= 0 && $col < 8} {
            lappend moves [expr {$row * 8 + $col}]
        }
    }
    return $moves
}

# Return the number of available moves for this square
proc CheckSquare {square} {
    variable visited
    set moves 0
    foreach test [ValidMoves $square] {
        if {[lsearch -exact -integer $visited $test] == -1} {
        if {[lsearch -exact -integer $visited $test] < 0} {
            incr moves
        }
    }
    return $moves
}

# Select the next square to move to. Returns -1 if there are no available
# squares remaining that we can move to.
proc Next {square} {
    variable visited
    set minimum 9
    set nextSquare -1
    foreach testSquare [ValidMoves $square] {
        if {[lsearch -exact -integer $visited $testSquare] == -1} {
        if {[lsearch -exact -integer $visited $testSquare] < 0} {
            set count [CheckSquare $testSquare]
            if {$count < $minimum} {
                set minimum $count
                set nextSquare $testSquare
            } elseif {$count == $minimum} {
                # to remove the enhancement to Warnsdorff's rule
                # remove the next line:
186
187
188
189
190
191
192
193

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

209
210
211

212
213
214
215
216
217
218
186
187
188
189
190
191
192

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

208
209
210

211
212
213
214
215
216
217
218







-
+














-
+


-
+







    ttk::scale $dlg.tf.sc  -from 8 -to 2000 -command [list SetDelay] \
        -variable [namespace which -variable delay]
    ttk::checkbutton $dlg.tf.cc -text Repeat \
        -variable [namespace which -variable continuous]
    ttk::button $dlg.tf.b1 -text Start -command [list Tour $dlg]
    ttk::button $dlg.tf.b2 -text Exit -command [list Exit $dlg]
    set square 0
    for {set row 7} {$row != -1} {incr row -1} {
    for {set row 7} {$row >= 0} {incr row -1} {
        for {set col 0} {$col < 8} {incr col} {
            if {(($col & 1) ^ ($row & 1))} {
                set fill tan3 ; set dfill tan4
            } else {
                set fill bisque ; set dfill bisque3
            }
            set coords [list [expr {$col * 30 + 4}] [expr {$row * 30 + 4}] \
                            [expr {$col * 30 + 30}] [expr {$row * 30 + 30}]]
            $c create rectangle $coords -fill $fill -disabledfill $dfill \
                -width 2 -state disabled -outline black
        }
    }
    if {[tk windowingsystem] ne "x11"} {
        catch {eval font create KnightFont -size -24}
        $c create text 0 0 -font KnightFont -text "\u265e" \
        $c create text 0 0 -font KnightFont -text "" \
            -anchor nw -tags knight -fill black -activefill "#600000"
    } else {
        # On X11 we cannot reliably tell if the \u265e glyph is available
        # On X11 we cannot reliably tell if the  glyph is available
        # so just use a polygon
        set pts {
            2 25   24 25  21 19   20 8   14 0   10 0   0 13   0 16
            2 17    4 14   5 15    3 17   5 17   9 14  10 15  5 21
        }
        $c create polygon $pts -tag knight -offset 8 \
            -fill black -activefill "#600000"

Changes to library/demos/menu.tcl.

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







-
+







} elseif {[tk windowingsystem] == "win32"} {
    set modifier Control
} else {
    set modifier Meta
}
foreach i {A B C D E F} {
    $m add command -label "Print letter \"$i\"" -underline 14 \
	    -accelerator Meta+$i -command "puts $i" -accelerator $modifier+$i
	    -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" \
147
148
149
150
151
152
153



154
155
156















157
158
159
160
161
162
163
147
148
149
150
151
152
153
154
155
156



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178







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







		"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]} {

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 "\u03b8" -tags label_theta
$w.k create text 0 0 -anchor ne -text "\u03b4\u03b8" -tags label_dtheta
$w.k create text 0 0 -anchor ne -text "θ" -tags label_theta
$w.k create text 0 0 -anchor ne -text "δθ" -tags label_dtheta
pack $w.k -in $w.p.l2 -fill both -expand true

# Initialize some variables
set points {}
set Theta   45.0
set dTheta   0.0
set pi       3.1415926535897933

Changes to library/demos/spin.tcl.

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







-
+








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

Changes to library/demos/square.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15


16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20
21
22













-
-
+
+







#!/bin/sh
# the next line restarts using wish \
exec wish "$0" ${1+"$@"}

# square --
# This script generates a demo application containing only a "square"
# widget.  It's only usable in the "tktest" application or if Tk has
# been compiled with tkSquare.c. This demo arranges the following
# bindings for the widget:
#
# Button-1 press/drag:		moves square to mouse
# "a":				toggle size animation on/off

package require Tk		;# We use Tk generally, and...
package require Tktest		;# ... we use the square widget too.
package require tk		;# We use Tk generally, and...
package require tk::test	;# ... we use the square widget too.

square .s
pack .s -expand yes -fill both
wm minsize . 1 1

bind .s <Button-1> {center %x %y}
bind .s <B1-Motion> {center %x %y}

Added library/demos/systray.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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# systray.tcl --
#
# This demonstration script showcases the tk systray and tk sysnotify commands.
#

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

set w .systray
destroy $w
toplevel $w
wm title $w "System Tray Demonstration"
positionWindow $w

catch {tk systray destroy}
set trayIconExists false

set iconmenu .menubar
destroy $iconmenu
menu $iconmenu
$iconmenu add command -label "Status" -command { puts "status icon clicked" }
$iconmenu add command -label "Exit" -command exit

pack [label $w.l -text "This demonstration showcases
        the tk systray and tk sysnotify commands.
        Running this demo creates the systray icon.
        Clicking the buttons below modifies and destroys the icon
        and displays the notification."]

image create photo book -data R0lGODlhDwAPAKIAAP//////AP8AAMDAwICAgAAAAAAAAAAAACwAAAAADwAPAAADSQhA2u5ksPeKABKSCaya29d4WKgERFF0l1IMQCAKatvBJ0OTdzzXI1xMB3TBZAvATtB6NSLKleXi3OBoLqrVgc0yv+DVSEUuFxIAOw==

labelframe $w.f -text "Tray Icon"
button $w.f.b0 -text "Create" -command create
button $w.f.b1 -text "Modify" -command modify
button $w.f.b2 -text "Destroy" -command remove
pack $w.f.b0 $w.f.b1 $w.f.b2 -padx 5 -pady 3 -side left -expand true -fill x

button $w.b3 -text "Display Notification" -command notify
pack $w.f $w.b3 -expand true -fill x -padx 5 -pady 5

proc create {} {
    global trayIconExists
    if {$trayIconExists} {
        tk_messageBox -message "Systray icon already exists"
        return
    }
    tk systray create -image book -text "Systray sample" \
            -button1 {puts "foo"} \
            -button3 {tk_popup $iconmenu [winfo pointerx .] [winfo pointery .]}
    set trayIconExists true
}

proc modify {} {
    global trayIconExists
    if {!$trayIconExists} {
        tk_messageBox -message "Please create systray icon first"
        return
    }
    image create photo page -data R0lGODlhCwAPAKIAAP//////AMDAwICAgAAA/wAAAAAAAAAAACwAAAAACwAPAAADMzi6CzAugiAgDGE68aB0RXgRJBFVX0SNpQlUWfahQOvSsgrX7eZJMlQMWBEYj8iQchlKAAA7
    tk systray configure -image page
    tk systray configure -text "Modified text"
    tk systray configure -button1 {puts "this is a different output"}
    tk systray configure -button3 {puts "hello yall"}
}

proc notify {} {
    global trayIconExists
    if {!$trayIconExists} {
        tk_messageBox -message "Please create systray icon first"
        return
    }
    tk sysnotify  "Alert" "This is an alert"
}

proc remove {} {
    global trayIconExists
    if {!$trayIconExists} {
        tk_messageBox -message "Systray icon was already destroyed"
        return
    }
    tk systray destroy
    set trayIconExists false
}

create

## See Code / Dismiss buttons
pack [addSeeDismiss $w.buttons $w] -side bottom -fill x

Changes to library/demos/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





























































1
2
3
4
5
6
7
8



























































9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 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(arrowSetup) [list source [file join $dir arrow.tcl]]
set auto_index(arrowMove1) [list source [file join $dir arrow.tcl]]
set auto_index(arrowMove2) [list source [file join $dir arrow.tcl]]
set auto_index(arrowMove3) [list source [file join $dir arrow.tcl]]
set auto_index(textLoadFile) [list source [file join $dir search.tcl]]
set auto_index(textSearch) [list source [file join $dir search.tcl]]
set auto_index(textToggle) [list source [file join $dir search.tcl]]
set auto_index(itemEnter) [list source [file join $dir items.tcl]]
set auto_index(itemLeave) [list source [file join $dir items.tcl]]
set auto_index(itemMark) [list source [file join $dir items.tcl]]
set auto_index(itemStroke) [list source [file join $dir items.tcl]]
set auto_index(itemsUnderArea) [list source [file join $dir items.tcl]]
set auto_index(itemStartDrag) [list source [file join $dir items.tcl]]
set auto_index(itemDrag) [list source [file join $dir items.tcl]]
set auto_index(butPress) [list source [file join $dir items.tcl]]
set auto_index(loadDir) [list source [file join $dir image2.tcl]]
set auto_index(loadImage) [list source [file join $dir image2.tcl]]
set auto_index(rulerMkTab) [list source [file join $dir ruler.tcl]]
set auto_index(rulerNewTab) [list source [file join $dir ruler.tcl]]
set auto_index(rulerSelectTab) [list source [file join $dir ruler.tcl]]
set auto_index(rulerMoveTab) [list source [file join $dir ruler.tcl]]
set auto_index(rulerReleaseTab) [list source [file join $dir ruler.tcl]]
set auto_index(mkTextConfig) [list source [file join $dir ctext.tcl]]
set auto_index(textEnter) [list source [file join $dir ctext.tcl]]
set auto_index(textInsert) [list source [file join $dir ctext.tcl]]
set auto_index(textPaste) [list source [file join $dir ctext.tcl]]
set auto_index(textB1Press) [list source [file join $dir ctext.tcl]]
set auto_index(textB1Move) [list source [file join $dir ctext.tcl]]
set auto_index(textBs) [list source [file join $dir ctext.tcl]]
set auto_index(textDel) [list source [file join $dir ctext.tcl]]
set auto_index(bitmapRow) [list source [file join $dir bitmap.tcl]]
set auto_index(scrollEnter) [list source [file join $dir cscroll.tcl]]
set auto_index(scrollLeave) [list source [file join $dir cscroll.tcl]]
set auto_index(scrollButton) [list source [file join $dir cscroll.tcl]]
set auto_index(textWindOn) [list source [file join $dir twind.tcl]]
set auto_index(textWindOff) [list source [file join $dir twind.tcl]]
set auto_index(textWindPlot) [list source [file join $dir twind.tcl]]
set auto_index(embPlotDown) [list source [file join $dir twind.tcl]]
set auto_index(embPlotMove) [list source [file join $dir twind.tcl]]
set auto_index(textWindDel) [list source [file join $dir twind.tcl]]
set auto_index(embDefBg) [list source [file join $dir twind.tcl]]
set auto_index(floorDisplay) [list source [file join $dir floor.tcl]]
set auto_index(newRoom) [list source [file join $dir floor.tcl]]
set auto_index(roomChanged) [list source [file join $dir floor.tcl]]
set auto_index(bg1) [list source [file join $dir floor.tcl]]
set auto_index(bg2) [list source [file join $dir floor.tcl]]
set auto_index(bg3) [list source [file join $dir floor.tcl]]
set auto_index(fg1) [list source [file join $dir floor.tcl]]
set auto_index(fg2) [list source [file join $dir floor.tcl]]
set auto_index(fg3) [list source [file join $dir floor.tcl]]
set auto_index(setWidth) [list source [file join $dir hscale.tcl]]
set auto_index(plotDown) [list source [file join $dir plot.tcl]]
set auto_index(plotMove) [list source [file join $dir plot.tcl]]
set auto_index(puzzleSwitch) [list source [file join $dir puzzle.tcl]]
set auto_index(setHeight) [list source [file join $dir vscale.tcl]]
set auto_index(showMessageBox) [list source [file join $dir msgbox.tcl]]
set auto_index(setColor) [list source [file join $dir clrpick.tcl]]
set auto_index(setColor_helper) [list source [file join $dir clrpick.tcl]]
set auto_index(fileDialog) [list source [file join $dir filebox.tcl]]
set auto_index(arrowSetup) [list source -encoding utf-8 [file join $dir arrow.tcl]]
set auto_index(arrowMove1) [list source -encoding utf-8 [file join $dir arrow.tcl]]
set auto_index(arrowMove2) [list source -encoding utf-8 [file join $dir arrow.tcl]]
set auto_index(arrowMove3) [list source -encoding utf-8 [file join $dir arrow.tcl]]
set auto_index(textLoadFile) [list source -encoding utf-8 [file join $dir search.tcl]]
set auto_index(textSearch) [list source -encoding utf-8 [file join $dir search.tcl]]
set auto_index(textToggle) [list source -encoding utf-8 [file join $dir search.tcl]]
set auto_index(itemEnter) [list source -encoding utf-8 [file join $dir items.tcl]]
set auto_index(itemLeave) [list source -encoding utf-8 [file join $dir items.tcl]]
set auto_index(itemMark) [list source -encoding utf-8 [file join $dir items.tcl]]
set auto_index(itemStroke) [list source -encoding utf-8 [file join $dir items.tcl]]
set auto_index(itemsUnderArea) [list source -encoding utf-8 [file join $dir items.tcl]]
set auto_index(itemStartDrag) [list source -encoding utf-8 [file join $dir items.tcl]]
set auto_index(itemDrag) [list source -encoding utf-8 [file join $dir items.tcl]]
set auto_index(butPress) [list source -encoding utf-8 [file join $dir items.tcl]]
set auto_index(loadDir) [list source -encoding utf-8 [file join $dir image2.tcl]]
set auto_index(loadImage) [list source -encoding utf-8 [file join $dir image2.tcl]]
set auto_index(rulerMkTab) [list source -encoding utf-8 [file join $dir ruler.tcl]]
set auto_index(rulerNewTab) [list source -encoding utf-8 [file join $dir ruler.tcl]]
set auto_index(rulerSelectTab) [list source -encoding utf-8 [file join $dir ruler.tcl]]
set auto_index(rulerMoveTab) [list source -encoding utf-8 [file join $dir ruler.tcl]]
set auto_index(rulerReleaseTab) [list source -encoding utf-8 [file join $dir ruler.tcl]]
set auto_index(mkTextConfig) [list source -encoding utf-8 [file join $dir ctext.tcl]]
set auto_index(textEnter) [list source -encoding utf-8 [file join $dir ctext.tcl]]
set auto_index(textInsert) [list source -encoding utf-8 [file join $dir ctext.tcl]]
set auto_index(textPaste) [list source -encoding utf-8 [file join $dir ctext.tcl]]
set auto_index(textB1Press) [list source -encoding utf-8 [file join $dir ctext.tcl]]
set auto_index(textB1Move) [list source -encoding utf-8 [file join $dir ctext.tcl]]
set auto_index(textBs) [list source -encoding utf-8 [file join $dir ctext.tcl]]
set auto_index(textDel) [list source -encoding utf-8 [file join $dir ctext.tcl]]
set auto_index(bitmapRow) [list source -encoding utf-8 [file join $dir bitmap.tcl]]
set auto_index(scrollEnter) [list source -encoding utf-8 [file join $dir cscroll.tcl]]
set auto_index(scrollLeave) [list source -encoding utf-8 [file join $dir cscroll.tcl]]
set auto_index(scrollButton) [list source -encoding utf-8 [file join $dir cscroll.tcl]]
set auto_index(textWindOn) [list source -encoding utf-8 [file join $dir twind.tcl]]
set auto_index(textWindOff) [list source -encoding utf-8 [file join $dir twind.tcl]]
set auto_index(textWindPlot) [list source -encoding utf-8 [file join $dir twind.tcl]]
set auto_index(embPlotDown) [list source -encoding utf-8 [file join $dir twind.tcl]]
set auto_index(embPlotMove) [list source -encoding utf-8 [file join $dir twind.tcl]]
set auto_index(textWindDel) [list source -encoding utf-8 [file join $dir twind.tcl]]
set auto_index(embDefBg) [list source -encoding utf-8 [file join $dir twind.tcl]]
set auto_index(floorDisplay) [list source -encoding utf-8 [file join $dir floor.tcl]]
set auto_index(newRoom) [list source -encoding utf-8 [file join $dir floor.tcl]]
set auto_index(roomChanged) [list source -encoding utf-8 [file join $dir floor.tcl]]
set auto_index(bg1) [list source -encoding utf-8 [file join $dir floor.tcl]]
set auto_index(bg2) [list source -encoding utf-8 [file join $dir floor.tcl]]
set auto_index(bg3) [list source -encoding utf-8 [file join $dir floor.tcl]]
set auto_index(fg1) [list source -encoding utf-8 [file join $dir floor.tcl]]
set auto_index(fg2) [list source -encoding utf-8 [file join $dir floor.tcl]]
set auto_index(fg3) [list source -encoding utf-8 [file join $dir floor.tcl]]
set auto_index(setWidth) [list source -encoding utf-8 [file join $dir hscale.tcl]]
set auto_index(plotDown) [list source -encoding utf-8 [file join $dir plot.tcl]]
set auto_index(plotMove) [list source -encoding utf-8 [file join $dir plot.tcl]]
set auto_index(puzzleSwitch) [list source -encoding utf-8 [file join $dir puzzle.tcl]]
set auto_index(setHeight) [list source -encoding utf-8 [file join $dir vscale.tcl]]
set auto_index(showMessageBox) [list source -encoding utf-8 [file join $dir msgbox.tcl]]
set auto_index(setColor) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(setColor_helper) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(fileDialog) [list source -encoding utf-8 [file join $dir filebox.tcl]]
set auto_index(systray) [list source -encoding utf-8 [file join $dir systray.tcl]]

Changes to library/demos/tcolor.

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









-
+







#!/bin/sh
# the next line restarts using wish \
exec wish "$0" ${1+"$@"}

# tcolor --
# This script implements a simple color editor, where you can
# create colors using either the RGB, HSB, or CYM color spaces
# and apply the color to existing applications.

package require Tk 8.4
package require Tk
wm title . "Color Editor"

# Global variables that control the program:
#
# colorSpace -			Color space currently being used for
#				editing.  Must be "rgb", "cmy", or "hsb".
# label1, label2, label3 -	Labels for the scales.

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 \u201Ctoolbar style\u201D buttons by\
	buttons are configured to be toolbar style buttons by\
	telling them that they are to use the Toolbutton style. At the left\
	end of the toolbar is a simple marker that the cursor changes to a\
	movement icon over; drag that away from the toolbar to tear off the\
	whole toolbar into a separate toplevel widget. When the dragged-off\
	toolbar is no longer needed, just close it like any normal toplevel\
	and it will reattach to the window it was torn off from."

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 \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."
ttk::label $w.msg -font $font -wraplength 4i -justify left -text "Ttk is the new Tk themed widget set. This is a Ttk themed label, and below are three groups of Ttk widgets in Ttk labelframes. The first group are all buttons that set the current application theme when pressed. The second group contains three sets of checkbuttons, with a separator widget between the sets. Note that the Enabled button controls whether all the other themed widgets in this toplevel are in the disabled state. The third group has a collection of linked radiobuttons."
pack $w.msg -side top -fill x

## See Code / Dismiss
pack [addSeeDismiss $w.seeDismiss $w {enabled cheese tomato basil oregano happiness}]\
	-side bottom -fill x

## Add buttons for setting the theme

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 \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."
ttk::label $w.msg -font $font -wraplength 4i -justify left -text "Below are two progress bars. The top one is a determinate progress bar, which is used for showing how far through a defined task the program has got. The bottom one is an indeterminate progress bar, which is used to show that the program is busy but does not know how long for. Both are run here in self-animated mode, which can be turned on and off using the buttons underneath."
pack $w.msg -side top -fill x

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

ttk::frame $w.f

Changes to library/demos/unicodeout.tcl.

17
18
19
20
21
22
23
24

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

24


25
26
27
28
29
30
31







-
+
-
-







positionWindow $w

label $w.msg -font $font -wraplength 4i -anchor w -justify left \
	-text "This is a sample of Tk's support for languages that use\
	non-Western character sets.  However, what you will actually see\
	below depends largely on what character sets you have installed,\
	and what you see for characters that are not present varies greatly\
	between platforms as well.  The strings are written in Tcl using\
	between platforms as well."
	UNICODE characters using the \\uXXXX (or \\UXXXXXX) 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.
94
95
96
97
98
99
100
101

102
103
104
105
106

107
108
109
110
111
112
113




114
115
116
117
118

119
120
121
122

123
124
125

126
127
128


129
130
131
132


133
134
135
136

137
138
139
140
141
142
143
144
145
146
92
93
94
95
96
97
98

99


100
101

102


103




104
105
106
107


108
109

110

111
112

113

114

115



116
117




118
119

120


121





122
123
124
125
126







-
+
-
-


-
+
-
-

-
-
-
-
+
+
+
+
-
-


-
+
-


-
+
-

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

-
-
+
-
-
-
-
-





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"  "\u4E2D\u570B\u7684\u6F22\u5B57"
addSample $w "Simpl. Chinese" "\u6C49\u8BED"
addSample $w French "Langue fran\xE7aise"
addSample $w Greek \
addSample $w "Trad. Chinese"  "中國的漢字"
addSample $w "Simpl. Chinese" "汉语"
addSample $w French "Langue française"
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 Hindi "हिन्दी भाषा"
    "\u0939\u093F\u0928\u094D\u0926\u0940 \u092D\u093E\u0937\u093E"
addSample $w Icelandic "\xCDslenska"
addSample $w Japanese \
addSample $w Icelandic "Íslenska"
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 \
addSample $w Korean "대한민국의 한글"
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 "😀💩👍🇳🇱"
		"\U1F600\U1F4A9\U1F44D\U1F1F3\U1F1F1"
    } 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.

362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389


390
391
392
393
394
395
396
362
363
364
365
366
367
368

369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397







-




















+
+







    @@demo floor	A building floor plan
    @@demo cscroll	A simple scrollable canvas
    @@demo knightstour  A Knight's tour of the chess board

    @@subtitle	Scales and Progress Bars
    @@demo hscale	Horizontal scale
    @@demo vscale	Vertical scale
    @@new
    @@demo ttkscale	Themed scale linked to a label with traces
    @@demo ttkprogress	Progress bar

    @@subtitle	Paned Windows and Notebooks
    @@demo paned1	Horizontal paned window
    @@demo paned2	Vertical paned window
    @@demo ttkpane	Themed nested panes
    @@demo ttknote	Notebook widget

    @@subtitle	Menus and Toolbars
    @@demo menu		Menus and cascades (sub-menus)
    @@demo menubu	Menu-buttons
    @@demo ttkmenu	Themed menu buttons
    @@demo toolbar	Themed toolbar

    @@subtitle	Common Dialogs
    @@demo msgbox	Message boxes
    @@demo filebox	File selection dialog
    @@demo clrpick	Color picker
    @@demo fontchoose	Font selection dialog
    @@new
    @@demo systray      System tray icon and notification

    @@subtitle	Animation
    @@demo anilabel	Animated labels
    @@demo aniwave	Animated wave
    @@demo pendulum	Pendulum simulation
    @@demo goldberg	A celebration of Rube Goldberg

512
513
514
515
516
517
518
519

520
521
522
523
524
525
526
513
514
515
516
517
518
519

520
521
522
523
524
525
526
527







-
+







    if {$i < 0} {
	return
    }
    set cursor [.t cget -cursor]
    .t configure -cursor [::ttk::cursor busy]
    update
    set demo [string range [lindex $tags $i] 5 end]
    uplevel 1 [list source [file join $tk_demoDirectory $demo.tcl]]
    uplevel 1 [list source -encoding utf-8 [file join $tk_demoDirectory $demo.tcl]]
    update
    .t configure -cursor $cursor

    .t tag add visited "$index linestart +1 chars" "$index lineend -1 chars"
}

# showStatus --
620
621
622
623
624
625
626

627
628
629
630
631
632
633
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 {}"
    $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 --
718
719
720
721
722
723
724
725
726
727
728




729
730
731
732
733
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 \u00a9 %s" {1996-1997 Sun Microsystems, Inc.}]
[mc "Copyright \u00a9 %s" {1997-2000 Ajuba Solutions, Inc.}]
[mc "Copyright \u00a9 %s" {2001-2009 Donal K. Fellows}]
[mc "Copyright \u00a9 %s" {2002-2007 Daniel A. Steffen}]"
"[mc "Copyright © %s" {1996-1997 Sun Microsystems, Inc.}]
[mc "Copyright © %s" {1997-2000 Ajuba Solutions, Inc.}]
[mc "Copyright © %s" {2001-2009 Donal K. Fellows}]
[mc "Copyright © %s" {2002-2007 Daniel A. Steffen}]"
}

# Local Variables:
# mode: tcl
# End:

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 (c) 1992-1993 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright © 1992-1993 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

#
# ::tk_dialog:

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 (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

#-------------------------------------------------------------------------
# Elements of tk::Priv that are used in this file:
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
68







-
+







	}
	%W insert insert [::tk::GetSelection %W CLIPBOARD]
	tk::EntrySeeInsert %W
    }
}
bind Entry <<Clear>> {
    # ignore if there is no selection
    catch { %W delete sel.first sel.last }
    catch {%W delete sel.first sel.last}
}
bind Entry <<PasteSelection>> {
    if {$tk_strictMotif || ![info exists tk::Priv(mouseMoved)]
	|| !$tk::Priv(mouseMoved)} {
	tk::EntryPaste %W %x
    }
}
115
116
117
118
119
120
121
122

123
124
125

126
127
128

129
130
131
132

133
134
135
136
137
138
139
115
116
117
118
119
120
121

122
123
124

125
126
127

128
129
130
131

132
133
134
135
136
137
138
139







-
+


-
+


-
+



-
+







    tk::CancelRepeat
}
bind Entry <Control-Button-1> {
    %W icursor @%x
}

bind Entry <<PrevChar>> {
    tk::EntrySetCursor %W [expr {[%W index insert] - 1}]
    tk::EntrySetCursor %W [expr {[%W index insert]-1}]
}
bind Entry <<NextChar>> {
    tk::EntrySetCursor %W [expr {[%W index insert] + 1}]
    tk::EntrySetCursor %W [expr {[%W index insert]+1}]
}
bind Entry <<SelectPrevChar>> {
    tk::EntryKeySelect %W [expr {[%W index insert] - 1}]
    tk::EntryKeySelect %W [expr {[%W index insert]-1}]
    tk::EntrySeeInsert %W
}
bind Entry <<SelectNextChar>> {
    tk::EntryKeySelect %W [expr {[%W index insert] + 1}]
    tk::EntryKeySelect %W [expr {[%W index insert]+1}]
    tk::EntrySeeInsert %W
}
bind Entry <<PrevWord>> {
    tk::EntrySetCursor %W [tk::EntryPreviousWord %W insert]
}
bind Entry <<NextWord>> {
    tk::EntrySetCursor %W [tk::EntryNextWord %W insert]
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221
205
206
207
208
209
210
211


212

213
214
215
216
217
218
219







-
-
+
-







bind Entry <Control-Key> {# nothing}
bind Entry <Escape> {# nothing}
bind Entry <Return> {# nothing}
bind Entry <KP_Enter> {# nothing}
bind Entry <Tab> {# nothing}
bind Entry <Prior> {# nothing}
bind Entry <Next> {# nothing}
if {[tk windowingsystem] eq "aqua"} {
    bind Entry <Command-Key> {# nothing}
bind Entry <Command-Key> {# nothing}
}
# Tk-on-Cocoa generates characters for these two keys. [Bug 2971663]
bind Entry <<NextLine>> {# nothing}
bind Entry <<PrevLine>> {# nothing}

# On Windows, paste is done using Shift-Insert.  Shift-Insert already
# generates the <<Paste>> event, so we don't need to do anything here.
if {[tk windowingsystem] ne "win32"} {
274
275
276
277
278
279
280
281

282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298


299
300
301
302
303




304
305

306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
272
273
274
275
276
277
278

279
280
281
282
283
284
285
286
287
288
289
290
291
292
293



294
295
296




297
298
299
300
301

302












303
304
305
306
307
308
309







-
+














-
-
-
+
+

-
-
-
-
+
+
+
+

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








# Bindings for IME text input and accents.

bind Entry <<TkStartIMEMarkedText>> {
    dict set ::tk::Priv(IMETextMark) "%W" [%W index insert]
}
bind Entry <<TkEndIMEMarkedText>> {
    if { [catch {dict get $::tk::Priv(IMETextMark) "%W"} mark] } {
    if {[catch {dict get $::tk::Priv(IMETextMark) "%W"} mark]} {
	bell
    } else {
	%W selection range $mark insert
    }
}
bind Entry <<TkClearIMEMarkedText>> {
    %W delete [dict get $::tk::Priv(IMETextMark) "%W"] [%W index insert]
}
bind Entry <<TkAccentBackspace>> {
    tk::EntryBackspace %W
}

# A few additional bindings of my own.

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.
#
387
388
389
390
391
392
393
394

395
396
397

398
399
400
401
402
403
404
372
373
374
375
376
377
378

379
380
381

382
383
384
385
386
387
388
389







-
+


-
+







		    $w selection clear
		}
	    }
	}
	word {
	    if {$cur < $anchor} {
		set before [tcl_wordBreakBefore [$w get] $cur]
		set after [tcl_wordBreakAfter [$w get] [expr {$anchor-1}]]
		set after [tcl_wordBreakAfter [$w get] $anchor-1]
	    } elseif {$cur > $anchor} {
		set before [tcl_wordBreakBefore [$w get] $anchor]
		set after [tcl_wordBreakAfter [$w get] [expr {$cur - 1}]]
		set after [tcl_wordBreakAfter [$w get] $cur-1]
	    } else {
		if {[$w index @$Priv(pressX)] < $anchor} {
		      incr anchor -1
		}
		set before [tcl_wordBreakBefore [$w get] $anchor]
		set after [tcl_wordBreakAfter [$w get] $anchor]
	    }
514
515
516
517
518
519
520
521
522
523



524
525
526
527
528
529
530
499
500
501
502
503
504
505



506
507
508
509
510
511
512
513
514
515







-
-
-
+
+
+







# Arguments:
# w -		The entry window in which to backspace.

proc ::tk::EntryBackspace w {
    if {[$w selection present]} {
	$w delete sel.first sel.last
    } else {
	set x [expr {[$w index insert] - 1}]
	if {$x >= 0} {
	    $w delete $x
	set x [$w index insert]
	if {$x > 0} {
	    $w delete [expr {$x-1}]
	}
	if {[$w index @0] >= [$w index insert]} {
	    set range [$w xview]
	    set left [lindex $range 0]
	    set right [lindex $range 1]
	    $w xview moveto [expr {$left - ($right - $left)/2.0}]
	}
571
572
573
574
575
576
577
578
579

580
581

582
583

584
585
586
587
588
589
590
556
557
558
559
560
561
562


563
564
565
566
567

568
569
570
571
572
573
574
575







-
-
+


+

-
+







# w -		The entry window.

proc ::tk::EntryTranspose w {
    set i [$w index insert]
    if {$i < [$w index end]} {
	incr i
    }
    set first [expr {$i-2}]
    if {$first < 0} {
    if {$i < 2} {
	return
    }
    set first [expr {$i-2}]
    set data [$w get]
    set new [string index $data [expr {$i-1}]][string index $data $first]
    set new [string index $data $i-1][string index $data $first]
    $w delete $first $i
    $w insert insert $new
    EntrySeeInsert $w
}

# ::tk::EntryNextWord --
# Returns the index of the next word position after a given position in the
656
657
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
641
642
643
644
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
















-
+
















-
+






-
-
-
-
-
-
-
-
-
# Arguments:
# w -	The entry window from which the text to get
# x -	x location on screen

proc ::tk::EntryScanDrag {w x} {
    # Make sure these exist, as some weird situations can trigger the
    # motion binding without the initial press.  [Bug #220269]
    if {![info exists ::tk::Priv(x)]} { set ::tk::Priv(x) $x }
    if {![info exists ::tk::Priv(x)]} {set ::tk::Priv(x) $x}
    # allow for a delta
    if {abs($x-$::tk::Priv(x)) > 2} {
	set ::tk::Priv(mouseMoved) 1
    }
    $w scan dragto $x
}

# ::tk::EntryGetSelection --
#
# Returns the selected text of the entry with respect to the -show option.
#
# Arguments:
# w -         The entry window from which the text to get

proc ::tk::EntryGetSelection {w} {
    set entryString [string range [$w get] [$w index sel.first] \
	    [expr {[$w index sel.last] - 1}]]
	    [$w index sel.last]-1]
    if {[$w cget -show] ne ""} {
	return [string repeat [string index [$w cget -show] 0] \
		[string length $entryString]]
    }
    return $entryString
}









Changes to library/focus.tcl.

1
2
3
4
5
6

7
8
9
10
11
12
13
1
2
3
4
5

6
7
8
9
10
11
12
13





-
+







# focus.tcl --
#
# This file defines several procedures for managing the input
# focus.
#
# Copyright (c) 1994-1995 Sun Microsystems, Inc.
# Copyright © 1994-1995 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# ::tk_focusNext --
# This procedure returns the name of the next window after "w" in

Changes to library/fontchooser.tcl.

1
2
3
4
5
6


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





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

40
41

42
43
44
45
46
47
48
1
2
3
4


5
6
7
8
9
10
11
12
13
14
15
16





17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

39
40

41
42
43
44
45
46
47
48




-
-
+
+










-
-
-
-
-
+
+
+
+
+

















-
+

-
+







# fontchooser.tcl -
#
#	A themeable Tk font selection dialog. See TIP #324.
#
# Copyright (C) 2008 Keith Vetter
# Copyright (C) 2008 Pat Thoyts <[email protected]>
# Copyright © 2008 Keith Vetter
# Copyright © 2008 Pat Thoyts <[email protected]>
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

namespace eval ::tk::fontchooser {
    variable S

    set S(W) .__tk__fontchooser
    set S(fonts) [lsort -dictionary [font families]]
    set S(styles) [list \
                       [::msgcat::mc "Regular"] \
                       [::msgcat::mc "Italic"] \
                       [::msgcat::mc "Bold"] \
                       [::msgcat::mc "Bold Italic"] \
                      ]
	[::msgcat::mc "Regular"] \
	[::msgcat::mc "Italic"] \
	[::msgcat::mc "Bold"] \
	[::msgcat::mc "Bold Italic"] \
    ]

    set S(sizes) {8 9 10 11 12 14 16 18 20 22 24 26 28 36 48 72}
    set S(strike) 0
    set S(under) 0
    set S(first) 1
    set S(sampletext) [::msgcat::mc "AaBbYyZz01"]
    set S(-parent) .
    set S(-title) [::msgcat::mc "Font"]
    set S(-command) ""
    set S(-font) TkDefaultFont
}

proc ::tk::fontchooser::Setup {} {
    variable S

    # Canonical versions of font families, styles, etc. for easier searching
    set S(fonts,lcase) {}
    foreach font $S(fonts) { lappend S(fonts,lcase) [string tolower $font]}
    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]}
    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
        }
    }
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122
123
124

125
126
127
128
129
130
131
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131







-
+









-
+







        return -code error -errorcode [list TK LOOKUP OPTION $option] \
	    "bad option \"$option\": must be\
            -command, -font, -parent, -title or -visible"
    }

    set cache [dict create -parent $S(-parent) -title $S(-title) \
                   -font $S(-font) -command $S(-command)]
    set r [tclParseConfigSpec [namespace which -variable S] $specs "" $args]
    set r [tclParseConfigSpec [namespace which -variable S] $specs DONTSETDEFAULTS $args]
    if {![winfo exists $S(-parent)]} {
	set code [list TK LOOKUP WINDOW $S(-parent)]
        set err "bad window path name \"$S(-parent)\""
        array set S $cache
        return -code error -errorcode $code $err
    }
    if {[string trim $S(-title)] eq ""} {
        set S(-title) [::msgcat::mc "Font"]
    }
    if {[winfo exists $S(W)] && [lsearch $args -font] != -1} {
    if {[winfo exists $S(W)] && ("-font" in $args)} {
	Init $S(-font)
	event generate $S(-parent) <<TkFontchooserFontChanged>>
    }
    return $r
}

proc ::tk::fontchooser::Create {} {
141
142
143
144
145
146
147



148
149
150
151

152
153
154
155
156
157
158
141
142
143
144
145
146
147
148
149
150
151
152
153

154
155
156
157
158
159
160
161







+
+
+



-
+







    if {![winfo exists $S(W)]} {
        toplevel $S(W) -class TkFontDialog
        if {[package provide tcltest] ne {}} {set ::tk_dialog $S(W)}
        wm withdraw $S(W)
        wm title $S(W) $S(-title)
        wm transient $S(W) [winfo toplevel $S(-parent)]

        set scaling [tk scaling]
        set sizeWidth [expr {int([string length [::msgcat::mc "&Size:"]] * $scaling)}]

        set outer [::ttk::frame $S(W).outer -padding {10 10}]
        ::tk::AmpWidget ::ttk::label $S(W).font -text [::msgcat::mc "&Font:"]
        ::tk::AmpWidget ::ttk::label $S(W).style -text [::msgcat::mc "Font st&yle:"]
        ::tk::AmpWidget ::ttk::label $S(W).size -text [::msgcat::mc "&Size:"]
        ::tk::AmpWidget ::ttk::label $S(W).size -text [::msgcat::mc "&Size:"] -width $sizeWidth
        ttk::entry $S(W).efont -width 18 \
            -textvariable [namespace which -variable S](font)
        ttk::entry $S(W).estyle -width 10 \
            -textvariable [namespace which -variable S](style)
        ttk::entry $S(W).esize -textvariable [namespace which -variable S](size) \
            -width 3 -validate key -validatecommand {string is double %P}

195
196
197
198
199
200
201
202

203
204
205
206
207
208
209
198
199
200
201
202
203
204

205
206
207
208
209
210
211
212







-
+







        set minsize(fonts) \
            [expr {[font measure TkDefaultFont "Helvetica"] + $scroll_width}]
        set minsize(styles) \
            [expr {[font measure TkDefaultFont "Bold Italic"] + $scroll_width}]
        set minsize(sizes) \
            [expr {[font measure TkDefaultFont "-99"] + $scroll_width}]
        set min [expr {$minsize(gap) * 4}]
        foreach {what width} [array get minsize] { incr min $width }
        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]]
273
274
275
276
277
278
279
280

281
282
283
284
285
286
287
276
277
278
279
280
281
282

283
284
285
286
287
288
289
290







-
+







# ::tk::fontchooser::Done --
#
#       Handles teardown of the dialog, calling -command if needed
#
# Arguments:
#       ok              true if user pressed OK
#
proc ::tk::::fontchooser::Done {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]]
323
324
325
326
327
328
329
330

331
332

333
334

335
336

337
338
339
340
341
342
343
326
327
328
329
330
331
332

333
334

335
336

337
338

339
340
341
342
343
344
345
346







-
+

-
+

-
+

-
+







            destroy .___e
        }
        array set F [font actual $defaultFont]
        set S(font) $F(-family)
        set S(size) $F(-size)
        set S(strike) $F(-overstrike)
        set S(under) $F(-underline)
        set S(style) "Regular"
        set S(style) [::msgcat::mc "Regular"]
        if {$F(-weight) eq "bold" && $F(-slant) eq "italic"} {
            set S(style) "Bold Italic"
            set S(style) [::msgcat::mc "Bold Italic"]
        } elseif {$F(-weight) eq "bold"} {
            set S(style) "Bold"
            set S(style) [::msgcat::mc "Bold"]
        } elseif {$F(-slant) eq "italic"} {
            set S(style) "Italic"
            set S(style) [::msgcat::mc "Italic"]
        }

        set S(first) 0
    }

    Tracer a b c
    Update
377
378
379
380
381
382
383
384

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

400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415





416
417
418
419
420
421
422
380
381
382
383
384
385
386

387
388
389
390
391
392
393
394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409
410
411
412
413





414
415
416
417
418
419
420
421
422
423
424
425







-
+














-
+











-
-
-
-
-
+
+
+
+
+







    set nstate normal
    # Make selection in each listbox
    foreach var {font style size} {
        set value [string tolower $S($var)]
        $S(W).l${var}s selection clear 0 end
        set n [lsearch -exact $S(${var}s,lcase) $value]
        $S(W).l${var}s selection set $n
        if {$n != -1} {
        if {$n >= 0} {
            set S($var) [lindex $S(${var}s) $n]
            $S(W).e$var icursor end
            $S(W).e$var selection clear
        } else {                                ;# No match, try prefix
            # Size is weird: valid numbers are legal but don't display
            # unless in the font size list
            set n [lsearch -glob $S(${var}s,lcase) "$value*"]
            set bad 1
            if {$var ne "size" || ! [string is double -strict $value]} {
                set nstate disabled
            }
        }
        $S(W).l${var}s see $n
    }
    if {!$bad} { Update }
    if {!$bad} {Update}
    $S(W).ok configure -state $nstate
}

# ::tk::fontchooser::Update --
#
#       Shows a sample of the currently selected font
#
proc ::tk::fontchooser::Update {} {
    variable S

    set S(result) [list $S(font) $S(size)]
    if {$S(style) eq "Bold"} { lappend S(result) bold }
    if {$S(style) eq "Italic"} { lappend S(result) italic }
    if {$S(style) eq "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)
}

# ::tk::fontchooser::Visibility --
#
#	Notify the parent when the dialog visibility changes

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 (c) 1994-1998 Sun Microsystems, Inc.
# Copyright (c) 2009 Donal K. Fellows
# Copyright © 1994-1998 Sun Microsystems, Inc.
# Copyright © 2009 Donal K. Fellows
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# API Summary:
#	tk::IconList <path> ?<option> <value>? ...
#	<path> add <imageName> <itemList>
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







-
+







#	<path> see <index>
#	<path> selection anchor ?<int>?
#	<path> selection clear <first> ?<last>?
#	<path> selection get
#	<path> selection includes <item>
#	<path> selection set <first> ?<last>?

package require Tk 8.6
package require tk

::tk::Megawidget create ::tk::IconList ::tk::FocusableWidget {
    variable w canvas sbar accel accelCB fill font index \
	itemList itemsPerColumn list maxIH maxIW maxTH maxTW noScroll \
	numItems oldX oldY options rect selected selection textList
    constructor args {
	next {*}$args
442
443
444
445
446
447
448
449
450
451


452
453
454

455
456
457
458
459
460
461
462
463
464
465
466
467
442
443
444
445
446
447
448



449
450



451






452
453
454
455
456
457
458







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







	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 [expr {40 * (%D)}]}]
	    bind $canvas <Option-Shift-MouseWheel>	[namespace code {my MouseWheel [expr {400 * (%D)}]}]
	bind $canvas <Shift-MouseWheel>	[namespace code {my MouseWheel %D}]
	bind $canvas <Option-Shift-MouseWheel>	[namespace code {my MouseWheel %D -12}]
	} 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 <Button-6>		[namespace code {my MouseWheel 120}]
	    bind $canvas <Button-7>		[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}]
501
502
503
504
505
506
507
508

509
510
511
512
513
514
515
516
517
518
519
520
521

522
523
524
525
526
527
528
529
492
493
494
495
496
497
498

499
500
501
502










503

504
505
506
507
508
509
510







-
+



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







	my Motion1 $x $y
	set ::tk::Priv(afterId) [after 50 [namespace code {my AutoScan}]]
    }

    # ----------------------------------------------------------------------

    # Event handlers
    method MouseWheel {amount} {
    method MouseWheel {amount {factor -120.0}} {
	if {$noScroll || $::tk_strictMotif} {
	    return
	}
	# We must make sure that positive and negative movements are rounded
	# equally to integers, avoiding the problem that
	#     (int)1/120 = 0,
	# but
	#     (int)-1/120 = -1
	# The following code ensure equal +/- behaviour.
	if {$amount > 0} {
	    $canvas xview scroll [expr {(-119-$amount) / 120}] units
	} else {
	    $canvas xview scroll [expr {-($amount / 120)}] units
	$canvas xview scroll [expr {$amount/$factor}] units
	}
    }
    method Btn1 {x y} {
	focus $canvas
	set i [$w index @$x,$y]
	if {$i eq ""} {
	    return
	}
701
702
703
704
705
706
707
708

709
710
711
712
713
714
715
682
683
684
685
686
687
688

689
690
691
692
693
694
695
696







-
+







		set i 0
	    }
	    if {$i == $start} {
		break
	    }
	}

	if {$theIndex > -1} {
	if {$theIndex >= 0} {
	    $w selection clear 0 end
	    $w selection set $theIndex
	    $w selection anchor $theIndex
	    $w see $theIndex
	}
    }
    method Reset {} {

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/)
#
#	See http://tango.freedesktop.org/Tango_Desktop_Project
#
# Copyright (c) 2009 Pat Thoyts <[email protected]>
# Copyright © 2009 Pat Thoyts <[email protected]>

namespace eval ::tk::icons {}

image create photo ::tk::icons::warning -data {
    iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAABSZJREFU
    WIXll1toVEcYgL+Zc87u2Yu7MYmrWRuTJuvdiMuqiJd4yYKXgMQKVkSjFR80kFIVJfWCWlvpg4h9
    8sXGWGof8iKNICYSo6JgkCBEJRG8ImYThNrNxmaTeM7pQ5IlJkabi0/9YZhhZv7///4z/8zPgf+7

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 (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1995 Sun Microsystems, Inc.
# Copyright (c) 1998 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 1998 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:
#
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187




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

204
205
206
207
208

209
210

211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
226
227

228
229

230
231
232
233
234
235
236
237
238
239
240
241

242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
172
173
174
175
176
177
178









179
180
181
182
















183





184


185








186









187


188












189












190
191
192
193
194
195
196







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







bind Listbox <Button-2> {
    %W scan mark %x %y
}
bind Listbox <B2-Motion> {
    %W scan dragto %x %y
}

# The MouseWheel will typically only fire on Windows and Mac OS X.
# However, someone could use the "event generate" command to produce
# one on other platforms.

if {[tk windowingsystem] eq "aqua"} {
    bind Listbox <MouseWheel> {
        %W yview scroll [expr {-(%D)}] units
    }
    bind Listbox <Option-MouseWheel> {
bind Listbox <MouseWheel> {
    tk::MouseWheel %W y %D -40.0
}
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 {
    # We must make sure that positive and negative movements are rounded
    # equally to integers, avoiding the problem that
    #     (int)1/30 = 0,
    # but
    #     (int)-1/30 = -1
    # The following code ensure equal +/- behaviour.
    bind Listbox <MouseWheel> {
    tk::MouseWheel %W y %D -12.0
	if {%D >= 0} {
	    %W yview scroll [expr {-%D/30}] units
	} else {
	    %W yview scroll [expr {(29-%D)/30}] units
	}
}
    }
    bind Listbox <Shift-MouseWheel> {
bind Listbox <Shift-MouseWheel> {
	if {%D >= 0} {
	    %W xview scroll [expr {-%D/30}] units
	} else {
	    %W xview scroll [expr {(29-%D)/30}] units
	}
    }
}

    tk::MouseWheel %W x %D -40.0
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:
    #	http://linuxreviews.org/howtos/xfree/mouse/
    bind Listbox <Button-4> {
	if {!$tk_strictMotif} {
	    %W yview scroll -5 units
	}
}
    }
    bind Listbox <Shift-Button-4> {
bind Listbox <Shift-Option-MouseWheel> {
	if {!$tk_strictMotif} {
	    %W xview scroll -5 units
	}
    }
    bind Listbox <Button-5> {
	if {!$tk_strictMotif} {
	    %W yview scroll 5 units
	}
    }
    bind Listbox <Shift-Button-5> {
	if {!$tk_strictMotif} {
	    %W xview scroll 5 units
    tk::MouseWheel %W x %D -12.0
	}
    }
    bind Listbox <Button-6> {
	if {!$tk_strictMotif} {
	    %W xview scroll -5 units
	}
    }
    bind Listbox <Button-7> {
	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;
323
324
325
326
327
328
329
330

331
332
333
334
335
336

337
338
339
340
341
342
343
259
260
261
262
263
264
265

266
267
268
269
270
271

272
273
274
275
276
277
278
279







-
+





-
+







		$w selection clear $i $el
		$w selection clear anchor $el
	    }
	    if {![info exists Priv(listboxSelection)]} {
		set Priv(listboxSelection) [$w curselection]
	    }
	    while {($i < $el) && ($i < $anchor)} {
		if {[lsearch $Priv(listboxSelection) $i] >= 0} {
		if {$i in $Priv(listboxSelection)} {
		    $w selection set $i
		}
		incr i
	    }
	    while {($i > $el) && ($i > $anchor)} {
		if {[lsearch $Priv(listboxSelection) $i] >= 0} {
		if {$i in $Priv(listboxSelection)} {
		    $w selection set $i
		}
		incr i -1
	    }
	    set Priv(listboxPrev) $el
	    tk::FireListboxSelectEvent $w
	}
529
530
531
532
533
534
535
536

537
538
539
540
541
542
543
465
466
467
468
469
470
471

472
473
474
475
476
477
478
479







-
+







    if {$first > $last} {
	set tmp $first
	set first $last
	set last $tmp
    }
    $w selection clear $first $last
    while {$first <= $last} {
	if {[lsearch $Priv(listboxSelection) $first] >= 0} {
	if {$first in $Priv(listboxSelection)} {
	    $w selection set $first
	}
	incr first
    }
    tk::FireListboxSelectEvent $w
}

Changes to library/megawidget.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






-
+





-
+







# 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 (c) 2009-2010 Donal K. Fellows
# Copyright © 2009-2010 Donal K. Fellows
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

package require Tk 8.6
package require tk

::oo::class create ::tk::Megawidget {
    superclass ::oo::class
    method unknown {w args} {
	if {[string match .* $w]} {
	    [self] create $w {*}$args
	    return $w

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 (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright (c) 2007 Daniel A. Steffen <[email protected]>
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# Copyright © 2007 Daniel A. Steffen <[email protected]>
#
# 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:

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 (c) 1994-1997 Sun Microsystems, Inc.
# Copyright © 1994-1997 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# Ensure existence of ::tk::dialog namespace
#

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\u00E5"
    ::msgcat::mcset da "&Blue" "&Blå"
    ::msgcat::mcset da "Cancel" "Annuller"
    ::msgcat::mcset da "&Cancel" "&Annuller"
    ::msgcat::mcset da "Cannot change to the directory \"%1\$s\".\nPermission denied." "Kan ikke skifte til katalog \"%1\$s\".\nIngen rettigheder."
    ::msgcat::mcset da "Choose Directory" "V\u00E6lg katalog"
    ::msgcat::mcset da "Choose Directory" "Vælg katalog"
    ::msgcat::mcset da "Cl&ear" "&Ryd"
    ::msgcat::mcset da "&Clear Console" "&Ryd konsolen"
    ::msgcat::mcset da "Color" "Farve"
    ::msgcat::mcset da "Console" "Konsol"
    ::msgcat::mcset da "&Copy" "&Kopier"
    ::msgcat::mcset da "Cu&t" "Kli&p"
    ::msgcat::mcset da "&Delete" "&Slet"
27
28
29
30
31
32
33
34
35


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




49
50

51
52
53
54
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\u00F8n"
    ::msgcat::mcset da "&Help" "&Hj\u00E6lp"
    ::msgcat::mcset da "&Green" "&Grøn"
    ::msgcat::mcset da "&Help" "&Hjælp"
    ::msgcat::mcset da "Hi" "Hej"
    ::msgcat::mcset da "&Hide Console" "Skjul &konsol"
    ::msgcat::mcset da "&Ignore" "&Ignorer"
    ::msgcat::mcset da "Invalid file name \"%1\$s\"." "Ugyldig fil navn \"%1\$s\"."
    ::msgcat::mcset da "Log Files" "Logfiler"
    ::msgcat::mcset da "&No" "&Nej"
    ::msgcat::mcset da "&OK" "&O.K."
    ::msgcat::mcset da "OK" "O.K."
    ::msgcat::mcset da "Ok"
    ::msgcat::mcset da "Open" "\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 "Open" "Åbn"
    ::msgcat::mcset da "&Open" "&Åbn"
    ::msgcat::mcset da "Open Multiple Files" "Åbn flere filer"
    ::msgcat::mcset da "P&aste" "&Indsæt"
    ::msgcat::mcset da "&Quit" "&Afslut"
    ::msgcat::mcset da "&Red" "&R\u00F8d"
    ::msgcat::mcset da "&Red" "&Rød"
    ::msgcat::mcset da "Replace existing file?" "Erstat eksisterende fil?"
    ::msgcat::mcset da "&Retry" "&Gentag"
    ::msgcat::mcset da "&Save" "&Gem"
    ::msgcat::mcset da "Save As" "Gem som"
    ::msgcat::mcset da "Save To Log" "Gem i log"
    ::msgcat::mcset da "Select Log File" "V\u00E6lg logfil"
    ::msgcat::mcset da "Select a file to source" "V\u00E6lg k\u00F8rbar fil"
    ::msgcat::mcset da "Select Log File" "Vælg logfil"
    ::msgcat::mcset da "Select a file to source" "Vælg kørbar fil"
    ::msgcat::mcset da "&Selection:" "&Udvalg:"
    ::msgcat::mcset da "Show &Hidden Directories" "Vis &skjulte kataloger"
    ::msgcat::mcset da "Show &Hidden Files and Directories" "Vis &skjulte filer og kataloger"
    ::msgcat::mcset da "Skip Messages" "Overspring beskeder"
    ::msgcat::mcset da "&Source..." "&K\u00F8r..."
    ::msgcat::mcset da "&Source..." "&Kør..."
    ::msgcat::mcset da "Tcl Scripts" "Tcl-Skripter"
    ::msgcat::mcset da "Tcl for Windows" "Tcl for Windows"
    ::msgcat::mcset da "Text Files" "Tekstfiler"
    ::msgcat::mcset da "&Yes" "&Ja"
    ::msgcat::mcset da "abort" "afbryd"
    ::msgcat::mcset da "blue" "bl\u00E5"
    ::msgcat::mcset da "blue" "blå"
    ::msgcat::mcset da "cancel" "afbryd"
    ::msgcat::mcset da "extension"
    ::msgcat::mcset da "extensions"
    ::msgcat::mcset da "green" "gr\u00F8n"
    ::msgcat::mcset da "green" "grøn"
    ::msgcat::mcset da "ignore" "ignorer"
    ::msgcat::mcset da "ok"
    ::msgcat::mcset da "red" "r\u00F8d"
    ::msgcat::mcset da "red" "rød"
    ::msgcat::mcset da "retry" "gentag"
    ::msgcat::mcset da "yes" "ja"
}

Changes to library/msgs/de.msg.

48
49
50
51
52
53
54
55

56
57
58
59
60
61
62
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62







-
+







    ::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 \u00F6ffnen"
    ::msgcat::mcset de "Open Multiple Files" "Mehrere Dateien Öffnen"
    ::msgcat::mcset de "P&aste" "E&infügen"
    ::msgcat::mcset de "&Quit" "&Beenden"
    ::msgcat::mcset de "&Red" "&Rot"
    ::msgcat::mcset de "Regular" "Standard"
    ::msgcat::mcset de "Replace existing file?" "Existierende Datei ersetzen?"
    ::msgcat::mcset de "&Retry" "&Wiederholen"
    ::msgcat::mcset de "Sample" "Beispiel"

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 (c) 1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# The procedures below are here strictly for backward compatibility with
# Tk version 3.6 and earlier.  The procedures are no longer needed, so

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 (c) 1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# ::tk_optionMenu --
# This procedure creates an option button named $w and an associated

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 (c) 1995-1997 Sun Microsystems, Inc.
# Copyright © 1995-1997 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# ::tk_setPalette --
# Changes the default color scheme for a Tk application by setting

Changes to library/safetk.tcl.

1
2
3
4
5

6
7
8
9
10
11
12
13
14
15
16
17

18
19

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

33
34

35
36

37
38
39
40
41
42
43

44
45
46

47
48

49
50

51
52
53
54
55
56

57
58
59
60
61
62
63
64
65

66
67
68
69
70
71
72

73
74
75
76
77

78
79
80
81
82
83
84

85
86
87
88

89
90
91


92
93
94
95


96
97
98
99
100
101
102
1
2
3
4

5
6
7
8
9
10
11
12
13
14
15
16

17
18

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

32
33

34
35

36
37
38
39
40
41
42

43
44
45

46
47

48
49

50
51
52
53
54
55

56
57
58
59
60
61
62
63
64

65
66
67
68
69
70
71

72
73
74
75
76

77
78
79
80
81
82
83

84
85
86
87

88
89


90
91
92
93


94
95
96
97
98
99
100
101
102




-
+











-
+

-
+












-
+

-
+

-
+






-
+


-
+

-
+

-
+





-
+








-
+






-
+




-
+






-
+



-
+

-
-
+
+


-
-
+
+







# safetk.tcl --
#
# Support procs to use Tk in safe interpreters.
#
# Copyright (c) 1997 Sun Microsystems, Inc.
# Copyright © 1997 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

# see safetk.n for documentation

#
#
# Note: It is now ok to let untrusted code being executed
#       between the creation of the interp and the actual loading
#       of Tk in that interp because the C side Tk_Init will
#       now look up the master interp and ask its safe::TkInit
#       now look up the parent interp and ask its safe::TkInit
#       for the actual parameters to use for it's initialization (if allowed),
#       not relying on the slave state.
#       not relying on the child state.
#

# We use opt (optional arguments parsing)
package require opt 0.4.1;

namespace eval ::safe {

    # counter for safe toplevels
    variable tkSafeId 0
}

#
# tkInterpInit : prepare the slave interpreter for tk loading
# tkInterpInit : prepare the child interpreter for tk loading
#                most of the real job is done by loadTk
# returns the slave name (tkInterpInit does)
# returns the child name (tkInterpInit does)
#
proc ::safe::tkInterpInit {slave argv} {
proc ::safe::tkInterpInit {child argv} {
    global env tk_library

    # We have to make sure that the tk_library variable is normalized.
    set tk_library [file normalize $tk_library]

    # Clear Tk's access for that interp (path).
    allowTk $slave $argv
    allowTk $child $argv

    # Ensure tk_library and subdirs (eg, ttk) are on the access path
    ::interp eval $slave [list set tk_library [::safe::interpAddToAccessPath $slave $tk_library]]
    ::interp eval $child [list set tk_library [::safe::interpAddToAccessPath $child $tk_library]]
    foreach subdir [::safe::AddSubDirs [list $tk_library]] {
	::safe::interpAddToAccessPath $slave $subdir
	::safe::interpAddToAccessPath $child $subdir
    }
    return $slave
    return $child
}


# tkInterpLoadTk:
# Do additional configuration as needed (calling tkInterpInit)
# and actually load Tk into the slave.
# and actually load Tk into the child.
#
# Either contained in the specified windowId (-use) or
# creating a decorated toplevel for it.

# empty definition for auto_mkIndex
proc ::safe::loadTk {} {}

::tcl::OptProc ::safe::loadTk {
    {slave -interp "name of the slave interpreter"}
    {child -interp "name of the child interpreter"}
    {-use  -windowId {} "window Id to use (new toplevel otherwise)"}
    {-display -displayName {} "display name to use (current one otherwise)"}
} {
    set displayGiven [::tcl::OptProcArgGiven "-display"]
    if {!$displayGiven} {
	# Try to get the current display from "."
	# (which might not exist if the master is tk-less)
	# (which might not exist if the parent is tk-less)
	if {[catch {set display [winfo screen .]}]} {
	    if {[info exists ::env(DISPLAY)]} {
		set display $::env(DISPLAY)
	    } else {
		Log $slave "no winfo screen . nor env(DISPLAY)" WARNING
		Log $child "no winfo screen . nor env(DISPLAY)" WARNING
		set display ":0.0"
	    }
	}
    }

    # Get state for access to the cleanupHook.
    namespace upvar ::safe S$slave state
    namespace upvar ::safe S$child state

    if {![::tcl::OptProcArgGiven "-use"]} {
	# create a decorated toplevel
	lassign [tkTopLevel $slave $display] w use
	lassign [tkTopLevel $child $display] w use

	# set our delete hook (slave arg is added by interpDelete)
	# to clean up both window related code and tkInit(slave)
	# set our delete hook (child arg is added by interpDelete)
	# to clean up both window related code and tkInit(child)
	set state(cleanupHook) [list tkDelete {} $w]
    } else {
	# set our delete hook (slave arg is added by interpDelete)
	# to clean up tkInit(slave)
	# set our delete hook (child arg is added by interpDelete)
	# to clean up tkInit(child)
	set state(cleanupHook) [list disallowTk]

	# Let's be nice and also accept tk window names instead of ids
	if {[string match ".*" $use]} {
	    set windowName $use
	    set use [winfo id $windowName]
	    set nDisplay [winfo screen $windowName]
118
119
120
121
122
123
124
125
126


127
128

129
130

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


125
126
127

128
129

130
131
132
133
134
135
136
137







-
-
+
+

-
+

-
+







		    "conflicting -display $display and -use $use -> $nDisplay"
	    } else {
		set display $nDisplay
	    }
	}
    }

    # Prepares the slave for tk with those parameters
    tkInterpInit $slave [list "-use" $use "-display" $display]
    # Prepares the child for tk with those parameters
    tkInterpInit $child [list "-use" $use "-display" $display]

    load {} Tk $slave
    load {} Tk $child

    return $slave
    return $child
}

proc ::safe::TkInit {interpPath} {
    variable tkInit
    if {[info exists tkInit($interpPath)]} {
	set value $tkInit($interpPath)
	Log $interpPath "TkInit called, returning \"$value\"" NOTICE
145
146
147
148
149
150
151
152

153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191

192
193
194
195
196

197
198
199
200
201
202
203
204




205
206
207
208

209
210
211
212
213


214
215
216
217

218
219
220
221
222
223

224
225

226
227

228
229
230
231
232
233
234
235
236
237
238
239

240
241
242
243
244
245
246
247
248
249
250

251
252
253
254
255
256
257
258
259
260
261
262
145
146
147
148
149
150
151

152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170

171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190

191
192
193
194
195

196
197
198
199
200




201
202
203
204
205
206
207

208
209
210
211


212
213
214
215
216

217
218
219
220
221
222

223
224

225
226

227
228
229
230
231
232
233
234
235
236
237
238

239
240
241
242
243
244
245
246
247
248
249

250
251
252
253
254
255
256
257
258
259
260
261
262







-
+


















-
+



















-
+




-
+




-
-
-
-
+
+
+
+



-
+



-
-
+
+



-
+





-
+

-
+

-
+











-
+










-
+













# safe::allowTk --
#
#	Set tkInit(interpPath) to allow Tk to be initialized in
#	safe::TkInit.
#
# Arguments:
#	interpPath	slave interpreter handle
#	interpPath	child interpreter handle
#	argv		arguments passed to safe::TkInterpInit
#
# Results:
#	none.

proc ::safe::allowTk {interpPath argv} {
    variable tkInit
    set tkInit($interpPath) $argv
    return
}


# safe::disallowTk --
#
#	Unset tkInit(interpPath) to disallow Tk from getting initialized
#	in safe::TkInit.
#
# Arguments:
#	interpPath	slave interpreter handle
#	interpPath	child interpreter handle
#
# Results:
#	none.

proc ::safe::disallowTk {interpPath} {
    variable tkInit
    # This can already be deleted by the DeleteHook of the interp
    if {[info exists tkInit($interpPath)]} {
	unset tkInit($interpPath)
    }
    return
}


# safe::tkDelete --
#
#	Clean up the window associated with the interp being deleted.
#
# Arguments:
#	interpPath	slave interpreter handle
#	interpPath	child interpreter handle
#
# Results:
#	none.

proc ::safe::tkDelete {W window slave} {
proc ::safe::tkDelete {W window child} {

    # we are going to be called for each widget... skip untill it's
    # top level

    Log $slave "Called tkDelete $W $window" NOTICE
    if {[::interp exists $slave]} {
	if {[catch {::safe::interpDelete $slave} msg]} {
	    Log $slave "Deletion error : $msg"
    Log $child "Called tkDelete $W $window" NOTICE
    if {[::interp exists $child]} {
	if {[catch {::safe::interpDelete $child} msg]} {
	    Log $child "Deletion error : $msg"
	}
    }
    if {[winfo exists $window]} {
	Log $slave "Destroy toplevel $window" NOTICE
	Log $child "Destroy toplevel $window" NOTICE
	destroy $window
    }

    # clean up tkInit(slave)
    disallowTk $slave
    # clean up tkInit(child)
    disallowTk $child
    return
}

proc ::safe::tkTopLevel {slave display} {
proc ::safe::tkTopLevel {child display} {
    variable tkSafeId
    incr tkSafeId
    set w ".safe$tkSafeId"
    if {[catch {toplevel $w -screen $display -class SafeTk} msg]} {
	return -code error -errorcode {TK TOPLEVEL SAFE} \
	    "Unable to create toplevel for safe slave \"$slave\" ($msg)"
	    "Unable to create toplevel for \"$child\" ($msg)"
    }
    Log $slave "New toplevel $w" NOTICE
    Log $child "New toplevel $w" NOTICE

    set msg "Untrusted Tcl applet ($slave)"
    set msg "Untrusted Tcl applet ($child)"
    wm title $w $msg

    # Control frame (we must create a style for it)
    ttk::style layout TWarningFrame {WarningFrame.border -sticky nswe}
    ttk::style configure TWarningFrame -background red

    set wc $w.fc
    ttk::frame $wc -relief ridge -borderwidth 4 -style TWarningFrame

    # We will destroy the interp when the window is destroyed
    bindtags $wc [concat Safe$wc [bindtags $wc]]
    bind Safe$wc <Destroy> [list ::safe::tkDelete %W $w $slave]
    bind Safe$wc <Destroy> [list ::safe::tkDelete %W $w $child]

    ttk::label $wc.l -text $msg -anchor w

    # We want the button to be the last visible item
    # (so be packed first) and at the right and not resizing horizontally

    # frame the button so it does not expand horizontally
    # but still have the default background instead of red one from the parent
    ttk::frame  $wc.fb -borderwidth 0
    ttk::button $wc.fb.b -text "Delete" \
	    -command [list ::safe::tkDelete $w $w $slave]
	    -command [list ::safe::tkDelete $w $w $child]
    pack $wc.fb.b -side right -fill both
    pack $wc.fb -side right -fill both -expand 1
    pack $wc.l -side left -fill both -expand 1 -ipady 2
    pack $wc -side bottom -fill x

    # Container frame
    frame $w.c -container 1
    pack $w.c -fill both -expand 1

    # return both the toplevel window name and the id to use for embedding
    list $w [winfo id $w.c]
}

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 (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1995 Sun Microsystems, Inc.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

#-------------------------------------------------------------------------
# The code below creates the default class bindings for entries.
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
56
57
58
59
60
61
62








63
64
65
66
67
68
69







-
-
-
-
-
-
-
-







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 <Button-3>	[bind Scale <Button-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> {
    tk::ScaleControlPress %W %x %y
}
bind Scale <<PrevLine>> {
    tk::ScaleIncrement %W up little noRepeat
}
bind Scale <<NextLine>> {

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 (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

#-------------------------------------------------------------------------
# The code below creates the default class bindings for scrollbars.
125
126
127
128
129
130
131
132
133
134
135
136
137





138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
125
126
127
128
129
130
131






132
133
134
135
136






















137
138
139
140
141
142
143







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







    tk::ScrollToPos %W 0
}
bind Scrollbar <<LineEnd>> {
    tk::ScrollToPos %W 1
}
}

if {[tk windowingsystem] eq "aqua"} {
    bind Scrollbar <MouseWheel> {
	tk::ScrollByUnits %W hv [expr {-(%D)}]
    }
    bind Scrollbar <Option-MouseWheel> {
	tk::ScrollByUnits %W hv [expr {-10 * (%D)}]
bind Scrollbar <MouseWheel> {
    tk::ScrollByUnits %W hv %D -40.0
}
bind Scrollbar <Option-MouseWheel> {
    tk::ScrollByUnits %W hv %D -12.0
    }
} else {
    # We must make sure that positive and negative movements are rounded
    # equally to integers, avoiding the problem that
    #     (int)1/30 = 0,
    # but
    #     (int)-1/30 = -1
    # The following code ensure equal +/- behaviour.
    bind Scrollbar <MouseWheel> {
	if {%D >= 0} {
	    tk::ScrollByUnits %W hv [expr {-%D/30}]
	} else {
	    tk::ScrollByUnits %W hv [expr {(29-%D)/30}]
	}
    }
}

if {[tk windowingsystem] eq "x11"} {
    bind Scrollbar <Button-4> {tk::ScrollByUnits %W hv -5}
    bind Scrollbar <Button-5> {tk::ScrollByUnits %W hv 5}
    bind Scrollbar <Button-6> {tk::ScrollByUnits %W hv -5}
    bind Scrollbar <Button-7> {tk::ScrollByUnits %W hv 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.
#
325
326
327
328
329
330
331
332

333
334
335
336
337
338
339
340

341
342

343
344
345
346
347
348
349
302
303
304
305
306
307
308

309
310
311
312
313
314
315
316

317
318

319
320
321
322
323
324
325
326







-
+







-
+

-
+







#
# Arguments:
# w -		The scrollbar widget.
# orient -	Which kinds of scrollbars this applies to:  "h" for
#		horizontal, "v" for vertical, "hv" for both.
# amount -	How many units to scroll:  typically 1 or -1.

proc ::tk::ScrollByUnits {w orient amount} {
proc ::tk::ScrollByUnits {w orient amount {factor 1.0}} {
    set cmd [$w cget -command]
    if {$cmd eq "" || ([string first \
	    [string index [$w cget -orient] 0] $orient] < 0)} {
	return
    }
    set info [$w get]
    if {[llength $info] == 2} {
	uplevel #0 $cmd scroll $amount units
	uplevel #0 $cmd scroll [expr {$amount/$factor}] units
    } else {
	uplevel #0 $cmd [expr {[lindex $info 2] + $amount}]
	uplevel #0 $cmd [expr {[lindex $info 2] + [expr {$amount/$factor}]}]
    }
}

# ::tk::ScrollByPages --
# This procedure tells the scrollbar's associated widget to scroll up
# or down by a given number of screenfuls.  It notifies the associated
# widget in different ways for old and new command syntaxes.

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 (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
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1999-2000 Jeffrey Hobbs
# Copyright © 2000 Ajuba Solutions
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

#-------------------------------------------------------------------------
# Elements of tk::Priv that are used in this file:
214
215
216
217
218
219
220
221
222

223
224
225
226
227
228
229
230
214
215
216
217
218
219
220


221

222
223
224
225
226
227
228







-
-
+
-







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 <Command-Key> {# nothing}
}

# On Windows, paste is done using Shift-Insert.  Shift-Insert already
# generates the <<Paste>> event, so we don't need to do anything here.
if {[tk windowingsystem] ne "win32"} {
    bind Spinbox <Insert> {
	catch {::tk::EntryInsert %W [::tk::GetSelection %W PRIMARY]}
    }
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291








292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
274
275
276
277
278
279
280









281
282
283
284
285
286
287
288












289
290
291
292
293
294
295







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







    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 <Button-2> {
    if {!$tk_strictMotif} {
	::tk::EntryScanMark %W %x
    }
}
bind Spinbox <B2-Motion> {
    if {!$tk_strictMotif} {
	::tk::EntryScanDrag %W %x
        }
    }
} else {
    bind Spinbox <Button-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:
479
480
481
482
483
484
485
486

487
488
489

490
491
492
493
494
495
496
464
465
466
467
468
469
470

471
472
473

474
475
476
477
478
479
480
481







-
+


-
+







		    $w selection clear
		}
	    }
	}
	word {
	    if {$cur < [$w index anchor]} {
		set before [tcl_wordBreakBefore [$w get] $cur]
		set after [tcl_wordBreakAfter [$w get] [expr {$anchor-1}]]
		set after [tcl_wordBreakAfter [$w get] $anchor-1]
	    } else {
		set before [tcl_wordBreakBefore [$w get] $anchor]
		set after [tcl_wordBreakAfter [$w get] [expr {$cur - 1}]]
		set after [tcl_wordBreakAfter [$w get] $cur-1]
	    }
	    if {$before < 0} {
		set before 0
	    }
	    if {$after < 0} {
		set after end
	    }
585
586
587
588
589
590
591
592

593
570
571
572
573
574
575
576

577
578







-
+

# a spinbox has no -show option to obscure contents.
#
# Arguments:
# w -         The spinbox window from which the text to get

proc ::tk::spinbox::GetSelection {w} {
    return [string range [$w get] [$w index sel.first] \
	    [expr {[$w index sel.last] - 1}]]
	    [$w index sel.last]-1]
}

Added library/systray.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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# systray.tcl --

# This file defines the 'tk systray' command for icon display and manipulation
# in the system tray on X11, Windows, and macOS, and the 'tk sysnotify' command
# for system alerts on each platform. It implements an abstraction layer that
# presents a consistent API across the three platforms.

# Copyright © 2020 Kevin Walzer/WordTech Communications LLC.
# Copyright © 2020 Eric Boudaillier.
# Copyright © 2020 Francois Vogel.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

# Pure-Tcl system tooltip window for use with system tray icon if native
# implementation not available.

namespace eval ::tk::systray {
    variable _created 0
    variable _options {-image "" -text "" -button1 "" -button3 ""}
    variable _current {}
    variable _ico

    proc _balloon {w help} {
	bind $w <Any-Enter> "after 1000 [list ::tk::systray::_balloon_show %W [list $help]]"
	bind $w <Any-Leave> "destroy %W._balloon"
    }

    proc _balloon_show {w arg} {
	if {[winfo containing {*}[winfo pointerxy .]] ne $w} {
	    return
	}
	set top $w._balloon
	catch {destroy $top}
	toplevel $top -bg black
	wm overrideredirect $top 1
	if {[tk windowingsystem] eq "aqua"}  {
	    ::tk::unsupported::MacWindowStyle style $top help none
	}
	pack [message $top._txt -aspect 10000 -text $arg]
	set wmx [winfo rootx $w]
	set wmy [expr {[winfo rooty $w] + [winfo height $w]}]
	wm geometry $top [winfo reqwidth $top._txt]x[winfo reqheight $top._txt]+$wmx+$wmy
	raise $top
    }

    proc _win_callback {msg} {
	variable _current
	# The API at the Tk level does not feature bindings to double clicks. Whatever
	# the speed the user clicks with, he expects the single click binding to fire.
	# Therefore we need to bind to both WM_*BUTTONDOWN and to WM_*BUTTONDBLCLK.
	switch -exact -- $msg {
	    WM_LBUTTONDOWN - WM_LBUTTONDBLCLK {
		uplevel #0 [dict get $_current -button1]
	    }
	    WM_RBUTTONDOWN - WM_RBUTTONDBLCLK {
		uplevel #0 [dict get $_current -button3]
	    }
	}
    }

    namespace export create configure destroy
    namespace ensemble create
}


# Pure-Tcl system notification window for use if native implementation not available.
namespace eval ::tk::sysnotify:: {

    proc _notifywindow {title msg} {
	catch {destroy ._notify}
	set w [toplevel ._notify]
	if {[tk windowingsystem] eq "aqua"} {
	    ::tk::unsupported::MacWindowStyle style $w utility {hud closeBox resizable}
	    wm title $w "Alert"
	}
	if {[tk windowingsystem] eq "win32"} {
	    wm attributes $w -toolwindow true
	    wm title $w "Alert"
	}
	label $w.l -bg gray30 -fg white -image ::tk::icons::information
	pack $w.l -fill both -expand yes -side left
	message $w.message -aspect 150 -bg gray30 -fg white -aspect 150 -text $title\n\n$msg -width 280
	pack $w.message -side right -fill both -expand yes
	if {[tk windowingsystem] eq "x11"} {
	    wm overrideredirect $w true
	}
	wm attributes $w -alpha 0.0
	set xpos [expr {[winfo screenwidth $w] - 325}]
	wm geometry $w +$xpos+30
	::tk::sysnotify::_fade_in $w
	after 3000 ::tk::sysnotify::_fade_out $w
    }

    #Fade and destroy window.
    proc _fade_out {w} {
	catch {
	    set prev_degree [wm attributes $w -alpha]
	    set new_degree [expr {$prev_degree - 0.05}]
	    set current_degree [wm attributes $w -alpha $new_degree]
	    if {$new_degree > 0.0 && $new_degree != $prev_degree} {
		after 10 [list ::tk::sysnotify::_fade_out $w]
	    } else {
		destroy $w
	    }
	}
    }

    #Fade the window into view.
    proc _fade_in {w} {
	catch {
	    raise $w
	    wm attributes $w -topmost 1
	    set prev_degree [wm attributes $w -alpha]
	    set new_degree [expr {$prev_degree + 0.05}]
	    set current_degree [wm attributes $w -alpha $new_degree]
	    focus -force $w
	    if {$new_degree < 0.9 && $new_degree != $prev_degree} {
		after 10 [list ::tk::sysnotify::_fade_in $w]
	    }
	}
    }
    namespace export *
}


# tk systray --
# This procedure creates an icon display in the platform-specific system tray.
#
# Subcommands:
#
#     create - create systray icon.
#         Arguments:
#             -image - Tk image to display.
#             -text - string to display in tooltip over image.
#             -button1 - Tcl proc to invoke on <Button-1> event.
#             -button3 - Tcl proc to invoke on <Button-3> event.
#
#     configure - change one of the systray properties.
#         Arguments (Any or all can be called):
#             -image - Tk image to update.
#             -text - string to update.
#             -button1 - Tcl proc to change for <Button-1> event.
#             -button3  - Tcl proc to change for <Button-3> event.
#
#     destroy - destroy systray icon.
#         Arguments:
#             none.
proc ::tk::systray::create {args} {
    variable _created
    variable _options
    variable _current
    variable _ico

    if {$_created} {
	return -code error -errorcode {TK SYSTRAY CREATE} "only one system tray icon supported per interpeter"
    }
    _check_options $args 0
    if {![dict exists $args -image]} {
	return -code error -errorcode {TK SYSTRAY CREATE} "missing required option \"-image\""
    }
    set values [dict merge $_options $args]
    try {
	switch -- [tk windowingsystem] {
	    "win32" {
		set _ico [_systray add -image [dict get $values -image] \
			-text [dict get $values -text] \
			-callback [list ::tk::systray::_win_callback %m]]
	    }
	    "x11" {
		_systray ._tray -image [dict get $values -image] -visible true
		_balloon ._tray [dict get $values -text]
		bind ._tray <Button-1> [dict get $values -button1]
		bind ._tray <Button-3> [dict get $values -button3]
	    }
	    "aqua" {
		_systray create [dict get $values -image] [dict get $values -text] \
			[dict get $values -button1] [dict get $values -button3]
	    }
	}
    } on ok {} {
	set _current $values
	set _created 1
	return
    } on error {msg opts} {
	return -code error -errorcode [dict get $opts -errorcode] $msg
    }
}

# Modify the systray icon.
proc ::tk::systray::configure {args} {
    variable _created
    variable _options
    variable _current
    variable _ico

    if {!$_created} {
	return -code error -errorcode {TK SYSTRAY CREATE} "systray not created"
    }
    _check_options $args 1
    if {[llength $args] == 0} {
	return $_current
    } elseif {[llength $args] == 1} {
	return [dict get $_current [lindex $args 0]]
    }
    set values [dict merge $_current $args]
    try {
	switch -- [tk windowingsystem] {
	    "win32" {
		if {[dict exists $args -image]} {
		    _systray modify $_ico -image [dict get $args -image]
		}
		if {[dict exists $args -text]} {
		    _systray modify $_ico -text [dict get $args -text]
		}
	    }
	    "x11" {
		if {[dict exists $args -image]} {
		    ._tray configure -image [dict get $args -image]
		}
		if {[dict exists $args -text]} {
		    _balloon ._tray [dict get $args -text]
		}
		if {[dict exists $args -button1]} {
		    bind ._tray <Button-1> [dict get $args -button1]
		}
		if {[dict exists $args -button3]} {
		    bind ._tray <Button-3> [dict get $args -button3]
		}
	    }
	    "aqua" {
		foreach {key opt} {image -image text \
			-text b1_callback -button1 b3_callback -button3} {
		    if {[dict exists $args $opt]} {
			_systray modify $key [dict get $args $opt]
		    }
		}
	    }
	}
    } on ok {} {
	set _current $values
	return
    } on error {msg opts} {
	return -code error -errorcode [dict get $opts -errorcode] $msg
    }
}


# Remove the systray icon.
proc ::tk::systray::destroy {} {
    variable _created
    variable _current
    variable _ico

    if {!$_created} {
	return -code error -errorcode {TK SYSTRAY DESTROY} "systray not created"
    }
    switch -- [tk windowingsystem] {
	"win32" {
	    _systray delete $_ico
	    set _ico ""
	}
	"x11" {
	    ::destroy ._tray
	}
	"aqua" {
	    _systray destroy
	}
    }
    set _created 0
    set _current {}
    return
}

# Check systray options
proc ::tk::systray::_check_options {argsList singleOk} {
    variable _options

    set len [llength $argsList]
    while {[llength $argsList] > 0} {
        set opt [lindex $argsList 0]
        if {![dict exists $_options $opt]} {
            tailcall return -code error -errorcode {TK SYSTRAY OPTION} \
		"unknown option \"$opt\": must be -image, -text, -button1 or -button3"
        }
        if {[llength $argsList] == 1 && !($len == 1 && $singleOk)} {
            tailcall return -code error -errorcode {TK SYSTRAY OPTION} \
		"missing value for option \"$opt\""
        }
        set argsList [lrange $argsList 2 end]
    }
}

# tk sysnotify --
# This procedure implements a platform-specific system notification alert.
#
#   Arguments:
#       title - main text of alert.
#       message - body text of alert.

proc ::tk::sysnotify::sysnotify {title message} {

    switch -- [tk windowingsystem] {
	"win32" {
	    if {!$::tk::systray::_created} {
		error "must create a system tray icon with the \"tk systray\" command first"
	    }
	    _sysnotify notify $::tk::systray::_ico $title $message
	}
	"x11" {
	    if {[info commands ::tk::sysnotify::_sysnotify] eq ""} {
		_notifywindow $title $message
	    } else {
		_sysnotify $title $message
	    }
	}
	"aqua" {
	    _sysnotify $title $message
	}
    }
    return
}

#Add these commands to the tk command ensemble: tk systray, tk sysnotify
#Thanks to Christian Gollwitzer for the guidance here
set map [namespace ensemble configure tk -map]
dict set map systray ::tk::systray
dict set map sysnotify ::tk::sysnotify::sysnotify
namespace ensemble configure tk -map $map

Changes to library/tclIndex.

195
196
197
198
199
200
201

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







+







set auto_index(::tk::TextPrevPos) [list source [file join $dir text.tcl]]
set auto_index(::tk::PlaceWindow) [list source [file join $dir tk.tcl]]
set auto_index(::tk::SetFocusGrab) [list source [file join $dir tk.tcl]]
set auto_index(::tk::RestoreFocusGrab) [list source [file join $dir tk.tcl]]
set auto_index(::tk::ScreenChanged) [list source [file join $dir tk.tcl]]
set auto_index(::tk::EventMotifBindings) [list source [file join $dir tk.tcl]]
set auto_index(::tk::CancelRepeat) [list source [file join $dir tk.tcl]]
set auto_index(::tk::MouseWheel) [list source [file join $dir tk.tcl]]
set auto_index(::tk::TabToWindow) [list source [file join $dir tk.tcl]]
set auto_index(::tk::dialog::file::) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::Config) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::Create) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::SetSelectMode) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::UpdateWhenIdle) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::Update) [list source [file join $dir tkfbox.tcl]]

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 (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# ::tk::TearoffMenu --
# Given the name of a menu, this procedure creates a torn-off menu
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







-
+







    }
    if {$y == 0} {
    	set y [winfo rooty $w]
	if {[tk windowingsystem] eq "aqua"} {
	    # Shift by height of tearoff entry minus height of window titlebar
	    catch {incr y [expr {[$w yposition 1] - 16}]}
	    # Avoid the native menu bar which sits on top of everything.
	    if {$y < 22} { set y 22 }
	    if {$y < 22} {set y 22}
	}
    }

    set parent [winfo parent $w]
    while {[winfo toplevel $parent] ne $parent \
	    || [winfo class $parent] eq "Menu"} {
	set parent [winfo parent $parent]
149
150
151
152
153
154
155
156

157
158

159
160

161
162
163
164
165
166
167
168
169
170
171
172
173

174
175

176
177
178

179
180
181
182
183
184
149
150
151
152
153
154
155

156
157

158
159

160
161
162
163
164
165
166
167
168
169
170
171
172

173
174

175
176
177

178
179
180
181
182
183
184







-
+

-
+

-
+












-
+

-
+


-
+






    # Duplicate the binding tags and bindings from the source menu.

    set tags [bindtags $src]
    set srcLen [string length $src]

    # Copy tags to x, replacing each substring of src with dst.

    while {[set index [string first $src $tags]] != -1} {
    while {[set index [string first $src $tags]] >= 0} {
	if {$index > 0} {
	    append x [string range $tags 0 [expr {$index - 1}]]$dst
	    append x [string range $tags 0 $index-1]$dst
	}
	set tags [string range $tags [expr {$index + $srcLen}] end]
	set tags [string range $tags $index+$srcLen end]
    }
    append x $tags

    bindtags $dst $x

    foreach event [bind $src] {
	unset x
	set script [bind $src $event]
	set eventLen [string length $event]

	# Copy script to x, replacing each substring of event with dst.

	while {[set index [string first $event $script]] != -1} {
	while {[set index [string first $event $script]] >= 0} {
	    if {$index > 0} {
		append x [string range $script 0 [expr {$index - 1}]]
		append x [string range $script 0 $index-1]
	    }
	    append x $dst
	    set script [string range $script [expr {$index + $eventLen}] end]
	    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 (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998 by Scriptics Corporation.
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998 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:
302
303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
318
302
303
304
305
306
307
308


309

310
311
312
313
314
315
316







-
-
+
-







# which is wrong.  Ditto for <Escape>.

bind Text <Alt-Key> {# nothing }
bind Text <Meta-Key> {# nothing}
bind Text <Control-Key> {# nothing}
bind Text <Escape> {# nothing}
bind Text <KP_Enter> {# nothing}
if {[tk windowingsystem] eq "aqua"} {
    bind Text <Command-Key> {# nothing}
bind Text <Command-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
481
482

483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
423
424
425
426
427
428
429









430
431
432
433
434
435
436
437












438
439
440
441
















442
443
444
445
446
447
448
449
450
451










452


















































453
454
455
456
457
458
459







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




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








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 <Button-2> {
    if {!$tk_strictMotif} {
	tk::TextScanMark %W %x %y
    }
}
bind Text <B2-Motion> {
    if {!$tk_strictMotif} {
	tk::TextScanDrag %W %x %y
        }
    }
} else {
    bind Text <Button-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> {
        %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> {
bind Text <MouseWheel> {
    tk::MouseWheel %W y %D -4.0 pixels
}
bind Text <Option-MouseWheel> {
    tk::MouseWheel %W y %D -1.2 pixels
}
bind Text <Shift-MouseWheel> {
    tk::MouseWheel %W x %D -4.0 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> {
    tk::MouseWheel %W x %D -1.2 pixels
	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:
    #	http://linuxreviews.org/howtos/xfree/mouse/
    bind Text <Button-4> {
	if {!$tk_strictMotif} {
	    %W yview scroll -50 pixels
	}
    }
    bind Text <Button-5> {
	if {!$tk_strictMotif} {
	    %W yview scroll 50 pixels
	}
    }
    bind Text <Shift-Button-4> {
	if {!$tk_strictMotif} {
	    %W xview scroll -50 pixels
	}
    }
    bind Text <Shift-Button-5> {
	if {!$tk_strictMotif} {
	    %W xview scroll 50 pixels
	}
    }
    bind Text <Button-6> {
	if {!$tk_strictMotif} {
	    %W xview scroll -50 pixels
	}
    }
    bind Text <Button-7> {
	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.
#
577
578
579
580
581
582
583
584
585
586
587
588

589
590
591
592
593
594
595
596
497
498
499
500
501
502
503





504

505
506
507
508
509
510
511







-
-
-
-
-
+
-







    # relative to the gap
    set bbox [$w bbox [$w index $anchorname]]
    if {$x > [lindex $bbox 0]} {
	$w mark gravity $anchorname right
    } else {
	$w mark gravity $anchorname left
    }
    # Allow focus in any case on Windows, because that will let the
    # selection be displayed even for state disabled text widgets.
    if {[tk windowingsystem] eq "win32" \
	    || [$w cget -state] eq "normal"} {
	focus $w
    focus $w
    }
    if {[$w cget -autoseparators]} {
	$w edit separator
    }
}

# ::tk::TextSelectTo --
# This procedure is invoked to extend the selection, typically when

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 (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 Ajuba Solutions.
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-2000 Ajuba Solutions.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.

# Verify that we have Tk binary and script components from the same release
package require -exact Tk  8.7a4
package require -exact tk  8.7a4

# Create a ::tk namespace
namespace eval ::tk {
    # Set up the msgcat commands
    namespace eval msgcat {
	namespace export mc mcmax
        if {[interp issafe] || [catch {package require msgcat}]} {
362
363
364
365
366
367
368



369
370
371
372
373
374
375
376
377
378
379
380
381

382
383
384
385
386
387
388
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376

377
378

379
380
381

382
383
384
385
386
387
388
389







+
+
+





-


-



-
+







    }
}

#----------------------------------------------------------------------
# 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 <<PasteSelection>>	<ButtonRelease-2>
	event add <<Undo>>		<Control-z> <Control-Lock-Z>
	event add <<Redo>>		<Control-Z> <Control-Lock-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 <<SelectAll>>		<Control-/>
	event add <<SelectNone>>	<Control-backslash>
	event add <<NextChar>>		<Right>
	event add <<SelectNextChar>>	<Shift-Right>
	event add <<PrevChar>>		<Left>
	event add <<SelectPrevChar>>	<Shift-Left>
	event add <<NextWord>>		<Control-Right>
	event add <<SelectNextWord>>	<Control-Shift-Right>
418
419
420
421
422
423
424
425
426
427
428
429
430

431
432
433
434
435
436
437
419
420
421
422
423
424
425

426
427

428

429
430
431
432
433
434
435
436







-


-

-
+







	# 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 <<PasteSelection>>	<ButtonRelease-2>
  	event add <<Undo>>		<Control-z> <Control-Lock-Z>
	event add <<Redo>>		<Control-y> <Control-Lock-Y>
	event add <<ContextMenu>>	<Button-3>

	event add <<SelectAll>>		<Control-slash> <Control-a> <Control-Lock-A>
	event add <<SelectAll>>		<Control-/> <Control-a> <Control-Lock-A>
	event add <<SelectNone>>	<Control-backslash>
	event add <<NextChar>>		<Right>
	event add <<SelectNextChar>>	<Shift-Right>
	event add <<PrevChar>>		<Left>
	event add <<SelectPrevChar>>	<Shift-Left>
	event add <<NextWord>>		<Control-Right>
	event add <<SelectNextWord>>	<Control-Shift-Right>
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
450
451
452
453
454
455
456

457

458
459
460
461
462
463
464







-

-







	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 <<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>
	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>
492
493
494
495
496
497
498
499

500
501
502
503
504
505
506
507
508
509
510

511
512
513
514
515
516
517
489
490
491
492
493
494
495

496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515







-
+











+








# ----------------------------------------------------------------------
# Read in files that define all of the class bindings.
# ----------------------------------------------------------------------

if {$::tk_library ne ""} {
    proc ::tk::SourceLibFile {file} {
        namespace eval :: [list source [file join $::tk_library $file.tcl]]
        namespace eval :: [list source -encoding utf-8 [file join $::tk_library $file.tcl]]
    }
    namespace eval ::tk {
	SourceLibFile icons
	SourceLibFile button
	SourceLibFile entry
	SourceLibFile listbox
	SourceLibFile menu
	SourceLibFile panedwindow
	SourceLibFile scale
	SourceLibFile scrlbar
	SourceLibFile spinbox
	SourceLibFile systray
	SourceLibFile text
    }
}

# ----------------------------------------------------------------------
# Default bindings for keyboard traversal.
# ----------------------------------------------------------------------
532
533
534
535
536
537
538







539
540
541
542
543
544
545
530
531
532
533
534
535
536
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:
623
624
625
626
627
628
629
630
631


632
633
634
635
636
637
638
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 slaves $path] [pack slaves $path] \
	    [place slaves $path]]
    set subwins [concat [grid content $path] [pack content $path] \
	    [place content $path]]
    if {$class eq "Canvas"} {
	foreach item [$path find all] {
	    if {[$path type $item] eq "window"} {
		set w [$path itemcget $item -window]
		if {$w ne ""} {lappend subwins $w}
	    }
	}
683
684
685
686
687
688
689

690

691
692

693
694
695
696
697
698
699
700
701
702
703
704

705
706
707
708
709
710
688
689
690
691
692
693
694
695

696
697
698
699
700
701
702
703
704
705
706
707
708
709
710

711
712
713
714
715
716
717







+
-
+


+











-
+






    }
}


if {[tk windowingsystem] eq "aqua"} {
    #stub procedures to respond to "do script" Apple Events
    proc ::tk::mac::DoScriptFile {file} {
	uplevel #0 $file
    	source $file
    	source -encoding utf-8 $file
    }
    proc ::tk::mac::DoScriptText {script} {
	uplevel #0 $script
    	eval $script
    }
}

# Create a dictionary to store the starting index of the IME marked
# text in an Entry or Text widget.

set ::tk::Priv(IMETextMark) [dict create]

# Run the Ttk themed widget set initialization
if {$::ttk::library ne ""} {
    uplevel \#0 [list source $::ttk::library/ttk.tcl]
    uplevel \#0 [list source -encoding utf-8 $::ttk::library/ttk.tcl]
}

# Local Variables:
# mode: tcl
# fill-column: 78
# End:

Changes to library/tkfbox.tcl.

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

14
15
16
17
18
19
20
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 (c) 1994-1998 Sun Microsystems, Inc.
# Copyright © 1994-1998 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

namespace eval ::tk::dialog {}
namespace eval ::tk::dialog::file {

Changes to library/ttk/aquaTheme.tcl.

31
32
33
34
35
36
37






38
39
40
41
42
43
44
45






46
47


48
49
50

51
52








53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127
128
129
130
31
32
33
34
35
36
37
38
39
40
41
42
43
44



45
46
47
48
49
50
51
52
53
54


55
56
57
58

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86


































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

102
103
104
105
106
107
108
109
110
111
112
113







+
+
+
+
+
+

-
-
-




+
+
+
+
+
+
-
-
+
+


-
+


+
+
+
+
+
+
+
+

















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















-
+











	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 {
		background systemTextBackgroundColor
		!focus systemUnemphasizedSelectedTextBackgroundColor
	    }

	# Spinbox
	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/button.tcl.

38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52







-
+







ttk::copyBindings TButton TRadiobutton

# ...plus a few more:

bind TRadiobutton <Up>  		{ ttk::button::RadioTraverse %W -1 }
bind TRadiobutton <Down> 		{ ttk::button::RadioTraverse %W +1 }

# bind TCheckbutton <plus> { %W select }
# bind TCheckbutton <+> { %W select }
# bind TCheckbutton <minus> { %W deselect }

# activate --
#	Simulate a button press: temporarily set the state to 'pressed',
#	then invoke the button.
#
proc ttk::button::activate {w} {

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
178
179
180
181
182
183
184

185
186
187
188



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206

207
208
209
210
211
212
213
214
215
216

217
218
219
220
221
222
223

224
225
226
227
228
229
230
231







-
+



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








-
+









-
+






-
+







    $cb selection range 0 end
    $cb icursor end
    event generate $cb <<ComboboxSelected>> -when mark
}

## Scroll -- Mousewheel binding
#
proc ttk::combobox::Scroll {cb dir} {
proc ttk::combobox::Scroll {cb dir {factor 1.0}} {
    $cb instate disabled { return }
    set max [llength [$cb cget -values]]
    set current [$cb current]
    incr current $dir
    if {$max != 0 && $current == $current % $max} {
	SelectEntry $cb $current
    if {$current < 0} {
	set index 0
    } else {
	set d [expr {$dir/$factor}]
	set index [expr {$current + int($d > 0 ? ceil($d) : floor($d))}]
	if {$index >= $max} {set index [expr {$max - 1}]}
	if {$index < 0} {set index 0}
    }
    if {$max != 0 && $index != $current} {
	SelectEntry $cb $index
    }
}

## LBSelected $lb -- Activation binding for listbox
#	Set the combobox value to the currently-selected listbox value
#	and unpost the listbox.
#
proc ttk::combobox::LBSelected {lb} {
    set cb [LBMaster $lb]
    set cb [LBMain $lb]
    LBSelect $lb
    Unpost $cb
    focus $cb
}

## LBCancel --
#	Unpost the listbox.
#
proc ttk::combobox::LBCancel {lb} {
    Unpost [LBMaster $lb]
    Unpost [LBMain $lb]
}

## LBTab -- Tab key binding for combobox listbox.
#	Set the selection, and navigate to next/prev widget.
#
proc ttk::combobox::LBTab {lb dir} {
    set cb [LBMaster $lb]
    set cb [LBMain $lb]
    switch -- $dir {
	next	{ set newFocus [tk_focusNext $cb] }
	prev	{ set newFocus [tk_focusPrev $cb] }
    }

    if {$newFocus ne ""} {
	LBSelect $lb
353
354
355
356
357
358
359



360
361
362
363
364
365
366
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376







+
+
+







#
proc ttk::combobox::PlacePopdown {cb popdown} {
    set x [winfo rootx $cb]
    set y [winfo rooty $cb]
    set w [winfo width $cb]
    set h [winfo height $cb]
    set style [$cb cget -style]
    if { $style eq {} } {
      set style TCombobox
    }
    set postoffset [ttk::style lookup $style -postoffset {} {0 0 0 0}]
    foreach var {x y w h} delta $postoffset {
    	incr $var $delta
    }

    set H [winfo reqheight $popdown]
    if {$y + $h + $H > [winfo screenheight $popdown]} {
407
408
409
410
411
412
413
414

415
416
417

418
419
420
421
422
423
424
425

426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442

443
444
445
417
418
419
420
421
422
423

424
425
426

427
428
429
430
431
432
433
434

435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451

452
453
454
455







-
+


-
+







-
+
















-
+



proc ttk::combobox::Unpost {cb} {
    if {[winfo exists $cb.popdown]} {
	wm withdraw $cb.popdown
    }
    grab release $cb.popdown ;# in case of stuck or unexpected grab [#1239190]
}

## LBMaster $lb --
## LBMain $lb --
#	Return the combobox main widget that owns the listbox.
#
proc ttk::combobox::LBMaster {lb} {
proc ttk::combobox::LBMain {lb} {
    winfo parent [winfo parent [winfo parent $lb]]
}

## LBSelect $lb --
#	Transfer listbox selection to combobox value.
#
proc ttk::combobox::LBSelect {lb} {
    set cb [LBMaster $lb]
    set cb [LBMain $lb]
    set selection [$lb curselection]
    if {[llength $selection] == 1} {
	SelectEntry $cb [lindex $selection 0]
    }
}

## LBCleanup $lb --
#	<Destroy> binding for combobox listboxes.
#	Cleans up by unsetting the linked textvariable.
#
#	Note: we can't just use { unset [%W cget -listvariable] }
#	because the widget command is already gone when this binding fires).
#	[winfo parent] still works, fortunately.
#
proc ttk::combobox::LBCleanup {lb} {
    variable Values
    unset Values([LBMaster $lb])
    unset Values([LBMain $lb])
}

#*EOF*

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 (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 2004, Joe English
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 2004, Joe English
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

namespace eval ttk {
    namespace eval entry {
78
79
80
81
82
83
84
85

86
87

88
89
90
91
92
93



94
95
96
97
98
99
100
101
102
103
104
105
78
79
80
81
82
83
84

85
86

87
88
89




90
91
92





93
94
95
96
97
98
99







-
+

-
+


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







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 (Button3 on Aqua) bindings:
## Button2 bindings:
#	Used for scanning and primary transfer.
#	Note: ButtonRelease-2 (ButtonRelease-3 on Aqua)
#	Note: ButtonRelease-2
#	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 }
132
133
134
135
136
137
138
139
140
141
142
143
144


145
146
147
148
149
150
151
126
127
128
129
130
131
132






133
134
135
136
137
138
139
140
141







-
-
-
-
-
-
+
+







bind TEntry <Alt-Key>			{# nothing}
bind TEntry <Meta-Key>			{# nothing}
bind TEntry <Control-Key> 		{# nothing}
bind TEntry <Escape> 			{# nothing}
bind TEntry <Return> 			{# nothing}
bind TEntry <KP_Enter> 			{# nothing}
bind TEntry <Tab> 			{# nothing}

# Argh.  Apparently on Windows, the NumLock modifier is interpreted
# as a Command modifier.
if {[tk windowingsystem] eq "aqua"} {
    bind TEntry <Command-Key>		{# nothing}
}
bind TEntry <Command-Key>		{# nothing}

# Tk-on-Cocoa generates characters for these two keys. [Bug 2971663]
bind TEntry <<PrevLine>>		{# nothing}
bind TEntry <<NextLine>>		{# nothing}

## Additional emacs-like bindings:
#
bind TEntry <Control-d>			{ ttk::entry::Delete %W }
175
176
177
178
179
180
181
182

183
184
185
186
187
188
189
165
166
167
168
169
170
171

172
173
174
175
176
177
178
179







-
+







#

## EntrySelection -- Return the selected text of the entry.
#	Raises an error if there is no selection.
#
proc ttk::entry::EntrySelection {w} {
    set entryString [string range [$w get] [$w index sel.first] \
	    [expr {[$w index sel.last] - 1}]]
	    [$w index sel.last]-1]
    if {[$w cget -show] ne ""} {
	return [string repeat [string index [$w cget -show] 0] \
		[string length $entryString]]
    }
    return $entryString
}

Changes to library/ttk/fonts.tcl.

74
75
76
77
78
79
80
81

82
83
84
85
86
87
88
74
75
76
77
78
79
80

81
82
83
84
85
86
87
88







-
+







	if {[info exists tcl_platform(osVersion)]} {
            if {$tcl_platform(osVersion) >= 5.0} {
                set F(family) "Tahoma"
            } else {
                set F(family) "MS Sans Serif"
            }
        } else {
            if {[lsearch -exact [font families] Tahoma] != -1} {
            if {[lsearch -exact [font families] Tahoma] >= 0} {
                set F(family) "Tahoma"
            } else {
                set F(family) "MS Sans Serif"
            }
        }
	set F(size) 8

Changes to library/ttk/menubutton.tcl.

220
221
222
223
224
225
226
227

228
229
230
231

232
233
234
235
236
237
238
220
221
222
223
224
225
226

227
228
229
230

231
232
233
234
235
236
237
238







-
+



-
+







    	tk_popup $menu [winfo rootx $menu] [winfo rooty $menu]
    }
}

# FindMenuEntry --
#	Hack to support tk_optionMenus.
#	Returns the index of the menu entry with a matching -label,
#	-1 if not found.
#	"" if not found.
#
proc ttk::menubutton::FindMenuEntry {menu s} {
    set last [$menu index last]
    if {$last eq "none"} {
    if {$last eq "none" || $last eq ""} {
	return ""
    }
    for {set i 0} {$i <= $last} {incr i} {
	if {![catch {$menu entrycget $i -label} label]
	    && ($label eq $s)} {
	    return $i
	}

Changes to library/ttk/notebook.tcl.

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







+
+







bind TNotebook <Control-Tab>		{ ttk::notebook::CycleTab %W  1; break }
bind TNotebook <Control-Shift-Tab>	{ ttk::notebook::CycleTab %W -1; break }
catch {
bind TNotebook <Control-ISO_Left_Tab>	{ ttk::notebook::CycleTab %W -1; break }
}
bind TNotebook <Destroy>		{ ttk::notebook::Cleanup %W }

ttk::bindMouseWheel TNotebook		[list ttk::notebook::CycleTab %W]

# ActivateTab $nb $tab --
#	Select the specified tab and set focus.
#
#  Desired behavior:
#	+ take focus when reselecting the currently-selected tab;
#	+ keep focus if the notebook already has it;
#	+ otherwise set focus to the first traversable widget
52
53
54
55
56
57
58
59

60
61



62
63
64




65
66
67
68
69
70
71
54
55
56
57
58
59
60

61
62
63
64
65
66



67
68
69
70
71
72
73
74
75
76
77







-
+


+
+
+
-
-
-
+
+
+
+







	ActivateTab $w $index
    }
}

# CycleTab --
#	Select the next/previous tab in the list.
#
proc ttk::notebook::CycleTab {w dir} {
proc ttk::notebook::CycleTab {w dir {factor 1.0}} {
    if {[$w index end] != 0} {
	set current [$w index current]
	set d [expr {$dir/$factor}]
	set d [expr {int($d > 0 ? ceil($d) : floor($d))}]
	set tabCount [$w index end]
	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 select [expr {($current + $d) % $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
	}
    }
}

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







-
-
-
+
+
-
-
-
-







	bind $top <Control-Next>             {+ttk::notebook::TLCycleTab %W  1}
	bind $top <Control-Prior>            {+ttk::notebook::TLCycleTab %W -1}
	bind $top <Control-Tab> 	     {+ttk::notebook::TLCycleTab %W  1}
	bind $top <Control-Shift-Tab>        {+ttk::notebook::TLCycleTab %W -1}
	catch {
	bind $top <Control-ISO_Left_Tab>     {+ttk::notebook::TLCycleTab %W -1}
	}
	if {[tk windowingsystem] eq "aqua"} {
	    bind $top <Option-Key> \
		+[list ttk::notebook::MnemonicActivation $top %K]
	bind $top <Option-Key> \
	    +[list ttk::notebook::MnemonicActivation $top %K]
	} else {
	    bind $top <Alt-Key> \
		+[list ttk::notebook::MnemonicActivation $top %K]
	}
	bind $top <Destroy> {+ttk::notebook::TLCleanup %W}
    }

    lappend TLNotebooks($top) $nb
}

# TLCleanup -- <Destroy> binding for traversal-enabled toplevels

Changes to library/ttk/scale.tcl.

1

2
3
4
5
6
7
8

1
2
3
4
5
6
7
8
-
+







# scale.tcl - Copyright (C) 2004 Pat Thoyts <[email protected]>
# scale.tcl - Copyright © 2004 Pat Thoyts <[email protected]>
#
# Bindings for the TScale widget

namespace eval ttk::scale {
    variable State
    array set State  {
	dragging 0

Changes to library/ttk/scrollbar.tcl.

15
16
17
18
19
20
21
22
23
24

25
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
15
16
17
18
19
20
21



22



23









24
25
26
27
28
29
30







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








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
set eventList [list <MouseWheel>]
bind TScrollbar <MouseWheel> [bind Scrollbar <MouseWheel>]
switch [tk windowingsystem] {
    aqua {
        lappend eventList <Option-MouseWheel>
bind TScrollbar <Option-MouseWheel> [bind Scrollbar <Option-MouseWheel>]
    }
    x11 {
        lappend eventList <Button-4> <Button-5> <Button-6> <Button-7>
    }
}
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
    }
}
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66

67
68
69
70
71
72
73
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61







-
+







+







proc ttk::scrollbar::Press {w x y} {
    variable State

    set State(xPress) $x
    set State(yPress) $y

    switch -glob -- [$w identify $x $y] {
    	*uparrow -
	*uparrow -
	*leftarrow {
	    ttk::Repeatedly Scroll $w -1 units
	}
	*downarrow -
	*rightarrow {
	    ttk::Repeatedly Scroll $w  1 units
	}
	*grip -
	*thumb {
	    set State(first) [lindex [$w get] 0]
	}
	*trough {
	    set f [$w fraction $x $y]
	    if {$f < [lindex [$w get] 0]} {
		# Clicked in upper/left trough
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119
120
121
122
123
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112







+












# 	Behaves exactly like scrollbar::Press, except that
#	clicking in the trough jumps to the the selected position.
#
proc ttk::scrollbar::Jump {w x y} {
    variable State

    switch -glob -- [$w identify $x $y] {
	*grip -
	*thumb -
	*trough {
	    set State(first) [$w fraction $x $y]
	    Moveto $w $State(first)
	    set State(xPress) $x
	    set State(yPress) $y
	}
	default {
	    Press $w $x $y
	}
    }
}

Changes to library/ttk/spinbox.tcl.

19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
35

36
37
38
39
40
41
42
43
44
45
46
47
48
49

50
51

52
53

54
55
56

57
58

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

73
74
75
76
77
78
79
80
81
82
83

84
85

86
87

88
89

90
91
92
93
94
95
96
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
34

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

49
50

51
52

53
54
55

56
57

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

72
73
74
75
76
77
78
79
80
81
82

83
84

85
86

87
88

89
90
91
92
93
94
95
96







-
+








-
+













-
+

-
+

-
+


-
+

-
+













-
+










-
+

-
+

-
+

-
+








bind TSpinbox <Up>			{ event generate %W <<Increment>> }
bind TSpinbox <Down> 			{ event generate %W <<Decrement>> }

bind TSpinbox <<Increment>>		{ ttk::spinbox::Spin %W +1 }
bind TSpinbox <<Decrement>> 		{ ttk::spinbox::Spin %W -1 }

ttk::bindMouseWheel TSpinbox 		[list ttk::spinbox::MouseWheel %W]
ttk::bindMouseWheel TSpinbox 		[list ttk::spinbox::Spin %W]

## Motion --
#	Sets cursor.
#
proc ttk::spinbox::Motion {w x y} {
    variable State
    ttk::saveCursor $w State(userConfCursor) [ttk::cursor text]
    if {   [$w identify $x $y] eq "textarea"
        && [$w instate {!readonly !disabled}]
	&& [$w instate {!readonly !disabled}]
    } {
	ttk::setCursor $w text
    } else {
	ttk::setCursor $w $State(userConfCursor)
    }
}

## Press --
#
proc ttk::spinbox::Press {w x y} {
    if {[$w instate disabled]} { return }
    focus $w
    switch -glob -- [$w identify $x $y] {
        *textarea	{ ttk::entry::Press $w $x }
	*textarea	{ ttk::entry::Press $w $x }
	*rightarrow	-
        *uparrow 	{ ttk::Repeatedly event generate $w <<Increment>> }
	*uparrow 	{ ttk::Repeatedly event generate $w <<Increment>> }
	*leftarrow	-
        *downarrow	{ ttk::Repeatedly event generate $w <<Decrement>> }
	*downarrow	{ ttk::Repeatedly event generate $w <<Decrement>> }
	*spinbutton {
	    if {$y * 2 >= [winfo height $w]} {
	    	set event <<Decrement>>
		set event <<Decrement>>
	    } else {
	    	set event <<Increment>>
		set event <<Increment>>
	    }
	    ttk::Repeatedly event generate $w $event
	}
    }
}

## DoubleClick --
#	Select all if over the text area; otherwise same as Press.
#
proc ttk::spinbox::DoubleClick {w x y} {
    if {[$w instate disabled]} { return }

    switch -glob -- [$w identify $x $y] {
        *textarea	{ SelectAll $w }
	*textarea	{ SelectAll $w }
	*		{ Press $w $x $y }
    }
}

proc ttk::spinbox::Release {w} {
    ttk::CancelRepeat
}

## MouseWheel --
#	Mousewheel callback.  Turn these into <<Increment>> (-1, up)
# 	or <<Decrement> (+1, down) events.
# 	or <<Decrement> (+1, down) events. Not used any more.
#
proc ttk::spinbox::MouseWheel {w dir} {
proc ttk::spinbox::MouseWheel {w dir {factor 1.0}} {
    if {[$w instate disabled]} { return }
    if {$dir < 0} {
    if {($dir < 0) ^ ($factor < 0)} {
	event generate $w <<Increment>>
    } else {
    } elseif {$dir != 0} {
	event generate $w <<Decrement>>
    }
}

## SelectAll --
#	Select widget contents.
#
130
131
132
133
134
135
136
137

138
139
140
141
142
143
144


145
146
147
148


149
150
151
152
153
154
155
156
157
158










159
160
161


162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179

180
181
182
183
184
185
186
187
188
189
190
191
130
131
132
133
134
135
136

137
138
139
140
141
142


143
144
145
146
147
148
149
150
151









152
153
154
155
156
157
158
159
160
161
162


163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181

182
183
184
185
186
187
188
189
190
191
192
193
194







-
+





-
-
+
+




+
+

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

-
-
+
+

















-
+













## Spin --
#	Handle <<Increment>> and <<Decrement>> events.
#	If -values is specified, cycle through the list.
#	Otherwise cycle through numeric range based on
#	-from, -to, and -increment.
#
proc ttk::spinbox::Spin {w dir} {
proc ttk::spinbox::Spin {w dir {factor -1.0}} {
    variable State

    if {[$w instate disabled]} { return }

    if {![info exists State($w,values.length)]} {
      set State($w,values.index) -1
      set State($w,values.last) {}
	set State($w,values.index) -1
	set State($w,values.last) {}
    }
    set State($w,values) [$w cget -values]
    set State($w,values.length) [llength $State($w,values)]

    set d [expr {-($dir/$factor)}]
    set d [expr {int($d > 0 ? ceil($d) : floor($d))}]
    if {$State($w,values.length) > 0} {
        set value [$w get]
        set current $State($w,values.index)
        if {$value ne $State($w,values.last)} {
            set current [lsearch -exact $State($w,values) $value]
        }
        set State($w,values.index) [Adjust $w [expr {$current + $dir}] 0 \
                [expr {$State($w,values.length) - 1}]]
        set State($w,values.last) [lindex $State($w,values) $State($w,values.index)]
        $w set $State($w,values.last)
	set value [$w get]
	set current $State($w,values.index)
	if {$value ne $State($w,values.last)} {
	    set current [lsearch -exact $State($w,values) $value]
	    if {$current < 0} {set current -1}
	}
	set State($w,values.index) [Adjust $w [expr {$current + $d}] 0 \
		[expr {$State($w,values.length) - 1}]]
	set State($w,values.last) [lindex $State($w,values) $State($w,values.index)]
	$w set $State($w,values.last)
    } else {
        if {[catch {
    	    set v [expr {[scan [$w get] %f] + $dir * [$w cget -increment]}]
	if {[catch {
	    set v [expr {[scan [$w get] %f] + $d * [$w cget -increment]}]
	}]} {
	    set v [$w cget -from]
	}
	$w set [FormatValue $w [Adjust $w $v [$w cget -from] [$w cget -to]]]
    }
    SelectAll $w
    uplevel #0 [$w cget -command]
}

## FormatValue --
#	Reformat numeric value based on -format.
#
proc ttk::spinbox::FormatValue {w val} {
    set fmt [$w cget -format]
    if {$fmt eq ""} {
	# Try to guess a suitable -format based on -increment.
	set delta [expr {abs([$w cget -increment])}]
        if {0 < $delta && $delta < 1} {
	if {0 < $delta && $delta < 1} {
	    # NB: This guesses wrong if -increment has more than 1
	    # significant digit itself, e.g., -increment 0.25
	    set nsd [expr {int(ceil(-log10($delta)))}]
	    set fmt "%.${nsd}f"
	} else {
	    set fmt "%.0f"
	}
    }
    return [format $fmt $val]
}

#*EOF*

Changes to library/ttk/ttk.tcl.

8
9
10
11
12
13
14
15
16
17



18
19
20
21
22
23
24
8
9
10
11
12
13
14



15
16
17
18
19
20
21
22
23
24







-
-
-
+
+
+







namespace eval ::ttk {
    variable library
    if {![info exists library]} {
	set library [file dirname [info script]]
    }
}

source [file join $::ttk::library fonts.tcl]
source [file join $::ttk::library cursors.tcl]
source [file join $::ttk::library utils.tcl]
source -encoding utf-8 [file join $::ttk::library fonts.tcl]
source -encoding utf-8 [file join $::ttk::library cursors.tcl]
source -encoding utf-8 [file join $::ttk::library utils.tcl]

## ttk::deprecated $old $new --
#	Define $old command as a deprecated alias for $new command
#	$old and $new must be fully namespace-qualified.
#
proc ttk::deprecated {old new} {
    interp alias {} $old {} ttk::do'deprecate $old $new
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111












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

126
127
128
129
130
131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
93
94
95
96
97
98
99












100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

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

138
139
140
141
142
143
144
145







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













-
+












-
+







    }
    ::ttk::style theme use $theme
    set currentTheme $theme
}

### Load widget bindings.
#
source [file join $::ttk::library button.tcl]
source [file join $::ttk::library menubutton.tcl]
source [file join $::ttk::library scrollbar.tcl]
source [file join $::ttk::library scale.tcl]
source [file join $::ttk::library progress.tcl]
source [file join $::ttk::library notebook.tcl]
source [file join $::ttk::library panedwindow.tcl]
source [file join $::ttk::library entry.tcl]
source [file join $::ttk::library combobox.tcl]	;# dependency: entry.tcl
source [file join $::ttk::library spinbox.tcl]  ;# dependency: entry.tcl
source [file join $::ttk::library treeview.tcl]
source [file join $::ttk::library sizegrip.tcl]
source -encoding utf-8 [file join $::ttk::library button.tcl]
source -encoding utf-8 [file join $::ttk::library menubutton.tcl]
source -encoding utf-8 [file join $::ttk::library scrollbar.tcl]
source -encoding utf-8 [file join $::ttk::library scale.tcl]
source -encoding utf-8 [file join $::ttk::library progress.tcl]
source -encoding utf-8 [file join $::ttk::library notebook.tcl]
source -encoding utf-8 [file join $::ttk::library panedwindow.tcl]
source -encoding utf-8 [file join $::ttk::library entry.tcl]
source -encoding utf-8 [file join $::ttk::library combobox.tcl]	;# dependency: entry.tcl
source -encoding utf-8 [file join $::ttk::library spinbox.tcl]  ;# dependency: entry.tcl
source -encoding utf-8 [file join $::ttk::library treeview.tcl]
source -encoding utf-8 [file join $::ttk::library sizegrip.tcl]

## Label and Labelframe bindings:
#  (not enough to justify their own file...)
#
bind TLabelframe <<Invoke>>	{ tk::TabToWindow [tk_focusNext %W] }
bind TLabel <<Invoke>>		{ tk::TabToWindow [tk_focusNext %W] }

### Load settings for built-in themes:
#
proc ttk::LoadThemes {} {
    variable library

    # "default" always present:
    uplevel #0 [list source [file join $library defaults.tcl]]
    uplevel #0 [list source -encoding utf-8 [file join $library defaults.tcl]]

    set builtinThemes [style theme names]
    foreach {theme scripts} {
	classic 	classicTheme.tcl
	alt 		altTheme.tcl
	clam 		clamTheme.tcl
	winnative	winTheme.tcl
	xpnative	{xpTheme.tcl vistaTheme.tcl}
	aqua 		aquaTheme.tcl
    } {
	if {[lsearch -exact $builtinThemes $theme] >= 0} {
            foreach script $scripts {
                uplevel #0 [list source [file join $library $script]]
                uplevel #0 [list source -encoding utf-8 [file join $library $script]]
            }
	}
    }
}

ttk::LoadThemes; rename ::ttk::LoadThemes {}

Changes to library/ttk/utils.tcl.

269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299


300
301
302
303
304
305
306
307
308
309


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

327
328
329
330
331
332
333
334
335
336
337
338

339
340
341

342
343
344
345


346
347

348
349
350
351
352
353
354
355
356
357

358
359
360
361
362
363
364
365


366
367
368
369
370
371
372
373
269
270
271
272
273
274
275















276
277
278
279
280
281
282


283
284
285
286
287







288
289











290
291
292
293


294












295



296




297
298


299










300








301
302






303
304







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







-
-
+
+



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




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


    }
}

### Mousewheel bindings.
#
# Platform inconsistencies:
#
# On X11, the server typically maps the mouse wheel to Button4 and Button5.
#
# On OSX, Tk generates sensible values for the %D field in <MouseWheel> events.
#
# On Windows, %D must be scaled by a factor of 120.
# In addition, Tk redirects mousewheel events to the window with
# keyboard focus instead of sending them to the window under the pointer.
# We do not attempt to fix that here, see also TIP#171.
#
# OSX conventionally uses Shift+MouseWheel for horizontal scrolling,
# and Option+MouseWheel for accelerated scrolling.
#
# The Shift+MouseWheel behavior is not conventional on Windows or most
# X11 toolkits, but it's useful.
#
# MouseWheel scrolling is accelerated on X11, which is conventional
# for Tk and appears to be conventional for other toolkits (although
# Gtk+ and Qt do not appear to use as large a factor).
#

## ttk::bindMouseWheel $bindtag $command...
#	Adds basic mousewheel support to $bindtag.
#	$command will be passed one additional argument
#	specifying the mousewheel direction (-1: up, +1: down).
#	$command will be passed two additional arguments
#	specifying the mousewheel change and a factor.
#

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 { [expr {-(%D)}]} ]
	bind $bindtag <Option-MouseWheel> [append callback { [expr {-10 *(%D)}]} ]
    bind $bindtag <MouseWheel> "$callback %D -120.0"
    bind $bindtag <Option-MouseWheel> "$callback %D -12.0"
    } else {
	# We must make sure that positive and negative movements are rounded
	# equally to integers, avoiding the problem that
	#     (int)1/120 = 0,
	# but
	#     (int)-1/120 = -1
	# The following code ensure equal +/- behaviour.
	bind $bindtag <MouseWheel> [append callback { [
	    expr {%D>=0 ? (-%D/120) : ((119-%D)/120)}
	]}]
    }
}

## Mousewheel bindings for standard scrollable widgets.
#
# Usage: [ttk::copyBindings TtkScrollable $bindtag]
#

# $bindtag should be for a widget that supports the
# standard scrollbar protocol.
#

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> {
bind TtkScrollable <MouseWheel> \
	%W yview scroll [expr {-(%D)}] units
    }
    bind TtkScrollable <Shift-MouseWheel> {
	{ tk::MouseWheel %W y %D -40.0 }
	%W xview scroll [expr {-(%D)}] units
    }
    bind TtkScrollable <Option-MouseWheel> {
	%W yview scroll  [expr {-10 * (%D)}] units
bind TtkScrollable <Option-MouseWheel> \
	{ tk::MouseWheel %W y %D -12.0 }
    }
    bind TtkScrollable <Shift-Option-MouseWheel> {
bind TtkScrollable <Shift-MouseWheel> \
	%W xview scroll [expr {-10 * (%D)}] units
    }
} else {
    # We must make sure that positive and negative movements are rounded
    # equally to integers, avoiding the problem that
    #     (int)1/120 = 0,
    # but
    #     (int)-1/120 = -1
    # The following code ensure equal +/- behaviour.
    bind TtkScrollable <MouseWheel> {
	{ tk::MouseWheel %W x %D -40.0 }
	if {%D >= 0} {
	    %W yview scroll [expr {-%D/120}] units
	} else {
	    %W yview scroll [expr {(119-%D)/120}] units
	}
    }
    bind TtkScrollable <Shift-MouseWheel> {
	if {%D >= 0} {
bind TtkScrollable <Shift-Option-MouseWheel> \
	{ tk::MouseWheel %W x %D -12.0 }
	    %W xview scroll [expr {-%D/120}] units
	} else {
	    %W xview scroll [expr {(119-%D)/120}] units
	}
    }
}

#*EOF*

Changes to library/ttk/vistaTheme.tcl.

65
66
67
68
69
70
71
72

73
74

75
76
77
78
79
80
81
65
66
67
68
69
70
71

72
73

74
75
76
77
78
79
80
81







-
+

-
+







            EDIT 3 {disabled 3 readonly 5 focus 4 hover 2 {} 1}
        ttk::style element create Combobox.rightdownarrow vsapi \
            COMBOBOX 6 {disabled 4 pressed 3 active 2 {} 1} \
            -syssize {SM_CXVSCROLL SM_CYVSCROLL}
        ttk::style layout TCombobox {
            Combobox.border -sticky nswe -border 0 -children {
                Combobox.rightdownarrow -side right -sticky ns
                Combobox.padding -expand 1 -sticky nswe -children {
                Combobox.padding -sticky nswe -children {
                    Combobox.background -sticky nswe -children {
                        Combobox.focus -expand 1 -sticky nswe -children {
                        Combobox.focus -sticky nswe -children {
                            Combobox.textarea -sticky nswe
                        }
                    }
                }
            }
        }
        # Vista.Combobox droplist frame
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







-
+







            -padding 1 -halfheight 1 \
            -syssize { SM_CXVSCROLL SM_CYVSCROLL }
        ttk::style layout TSpinbox {
            Spinbox.field -sticky nswe -children {
                Spinbox.background -sticky news -children {
                    Spinbox.padding -sticky news -children {
                        Spinbox.innerbg -sticky news -children {
                            Spinbox.textarea -expand 1
                            Spinbox.textarea
                        }
                    }
                    Spinbox.uparrow -side top -sticky ens
                    Spinbox.downarrow -side bottom -sticky ens
                }
            }
        }
199
200
201
202
203
204
205
206
207


208
209
210
211
212
213
214
215
216
217
218


219
220
221
222
223
224
225
226
227
228
229
230
199
200
201
202
203
204
205


206
207
208
209
210
211
212
213
214
215
216


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







-
-
+
+









-
-
+
+












        }

        # Scale
        ttk::style element create Horizontal.Scale.slider vsapi \
            TRACKBAR 3 {disabled 5 focus 4 pressed 3 active 2 {} 1} \
            -width 6 -height 12
        ttk::style layout Horizontal.TScale {
            Scale.focus -expand 1 -sticky nswe -children {
                Horizontal.Scale.trough -expand 1 -sticky nswe -children {
            Scale.focus -sticky nswe -children {
                Horizontal.Scale.trough -sticky nswe -children {
                    Horizontal.Scale.track -sticky we
                    Horizontal.Scale.slider -side left -sticky {}
                }
            }
        }
        ttk::style element create Vertical.Scale.slider vsapi \
            TRACKBAR 6 {disabled 5 focus 4 pressed 3 active 2 {} 1} \
            -width 12 -height 6
        ttk::style layout Vertical.TScale {
            Scale.focus -expand 1 -sticky nswe -children {
                Vertical.Scale.trough -expand 1 -sticky nswe -children {
            Scale.focus -sticky nswe -children {
                Vertical.Scale.trough -sticky nswe -children {
                    Vertical.Scale.track -sticky ns
                    Vertical.Scale.slider -side top -sticky {}
                }
            }
        }

        # Treeview
        ttk::style configure Item -padding {4 0 0 0}

        package provide ttk::theme::vista 1.0
    }
}

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 (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 Scriptics Corporation
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-2000 Scriptics Corporation
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

namespace eval ::tk::dialog {}
namespace eval ::tk::dialog::file {}

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.tk/software/tcltk/license.html">
  https:www.tcl.tk/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.

39
40
41
42
43
44
45












46
47
48
49
50
51
52
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64







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







TCLSH_DIR		?= ${PREFIX}/bin

# set to non-empty value to install manpages in addition to html help:
INSTALL_MANPAGES	?=

# set to non-empty value to build TkX11 instead of TkAqua:
TK_X11			?=

# Checks and overrides for subframework builds
ifeq (${SUBFRAMEWORK}_${TK_X11},1_)
ifeq (${DYLIB_INSTALL_DIR},)
	@echo "Cannot install subframework with empty DYLIB_INSTALL_DIR !" && false
endif
ifeq (${DESTDIR},)
	@echo "Cannot install subframework with empty DESTDIR !" && false
endif
override BUILD_DIR = ${DESTDIR}/build
override INSTALL_PATH = /Frameworks
endif

#-------------------------------------------------------------------------------------------------------
# meta targets

meta			:= all install embedded install-embedded clean distclean test

styles			:= develop deploy
84
85
86
87
88
89
90
91

92
93
94
95
96
97
98
96
97
98
99
100
101
102

103
104
105
106
107
108
109
110







-
+







OBJ_DIR			= ${OBJROOT}/${BUILD_STYLE}

empty			:=
space			:= ${empty} ${empty}
objdir			= $(subst ${space},\ ,${OBJ_DIR})

develop_make_args	:= BUILD_STYLE=Development CONFIGURE_ARGS=--enable-symbols
deploy_make_args	:= BUILD_STYLE=Deployment INSTALL_TARGET=install-strip
deploy_make_args	:= BUILD_STYLE=Deployment INSTALL_TARGET=install
embedded_make_args	:= EMBEDDED_BUILD=1
install_make_args	:= INSTALL_BUILD=1

${targets}:
	${MAKE} ${action}${PROJECT} \
	$(foreach s,${styles} embedded install,$(if $(findstring $s,$@),${${s}_make_args}))

207
208
209
210
211
212
213



214
215
216



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232


233
234
235
236
237
238
239
240

241

242
243
244
245
246
247
248
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248


249
250
251
252
253
254
255
256
257

258
259
260
261
262
263
264
265
266
267







+
+
+



+
+
+














-
-
+
+







-
+

+







	rm -f Tcl.framework && ln -s "${TCL_FRAMEWORK_DIR}/Tcl.framework" . ; fi
endif

install-${PROJECT}: build-${PROJECT}
ifeq (${EMBEDDED_BUILD}_${INSTALL_ROOT},1_)
	@echo "Cannot install-embedded with empty INSTALL_ROOT !" && false
endif
ifeq (${SUBFRAMEWORK}_${DYLIB_INSTALL_DIR},1_)
	@echo "Cannot install subframework with empty DYLIB_INSTALL_DIR !" && false
endif
ifeq (${EMBEDDED_BUILD},1)
	@rm -rf "${INSTALL_ROOT}/${LIBDIR}/Tk.framework"
endif
ifeq (${SUBFRAMEWORK},1)
	@rm -rf "${INSTALL_ROOT}/Frameworks/Tk.framework"
endif
	${DO_MAKE}
ifeq (${EMBEDDED_BUILD}_${TK_X11},1_)
# workaround bug with 'cp -pRH' on Darwin 6 and earlier
	@if [ "`uname -r | awk -F. '{print $$1}'`" -lt 7 ]; then \
	mkdir -p "${TOP_DIR}"/{"${TCL_FMWK_DIR}","${TK_FMWK_DIR}"}/PrivateHeaders; fi
endif
ifeq (${INSTALL_BUILD},1)
ifeq (${EMBEDDED_BUILD},1)
# if we are embedding frameworks, don't install wish
	@rm -f "${INSTALL_ROOT}${BINDIR}/${WISH}" && \
	rmdir -p "${INSTALL_ROOT}${BINDIR}" 2>&- || true
else
# install wish symbolic link
	@ln -fs ${WISH} "${INSTALL_ROOT}${BINDIR}/${wish}"
endif
endif
endif # embedded
endif # install
ifeq (${BUILD_STYLE}_${EMBEDDED_BUILD},Development_)
# keep copy of debug library around, so that
# Deployment build can be installed on top
# of Development build without overwriting
# the debug library
	@cd "${INSTALL_ROOT}${LIBDIR}/${PRODUCT_NAME}.framework/Versions/${VERSION}" && \
	ln -f "${PRODUCT_NAME}" "${PRODUCT_NAME}_debug"
endif
endif # Development, not embedded
ifeq (${TK_X11},)
ifeq (${SUBFRAMEWORK},)
ifeq (${EMBEDDED_BUILD},)
# install Wish.app link in APPLICATION_INSTALL_PATH and setup 'Wish Shell' compatibility links
	@cd "${TOP_DIR}" && if [ -n "${APP_DIR}" ]; then mkdir -p "./${APP_DIR}" && rm -rf "./${APP_DIR}/Wish.app" && \
	ln -fsh "./$$(echo "${APP_DIR}" | sed -e 's#/[^/][^/]*#/..#g')/${FMWK_DIR}/${PRODUCT_NAME}.framework/Resources/Wish.app" "./${APP_DIR}" && \
	ln -fsh Wish.app "./${APP_DIR}/Wish Shell.app"; fi && \
	ln -fsh Wish.app "./${TK_FMWK_DIR}/Resources/Wish Shell.app" && \
	ln -fsh Wish "./${TK_FMWK_DIR}/Resources/Wish.app/Contents/MacOS/Wish Shell"
268
269
270
271
272
273
274

275
276
277



278
279
280
281
282
283
284
287
288
289
290
291
292
293
294



295
296
297
298
299
300
301
302
303
304







+
-
-
-
+
+
+







	    install_name_tool -change $$(otool -L "$$1" | awk "/$$2\.framework.*[^:]\$$/ {print \$$1; sub(\"^.*/Frameworks\",\"@executable_path/../Frameworks\",\$$1); print \$$1}") "$$1"; \
	    chmod -RH a-w "$$1"; \
	} && \
	fix_install_id Frameworks/Tcl.framework/Tcl Tcl && fix_install_id Frameworks/Tk.framework/Tk Tk && \
	fix_install_name MacOS/Wish Tcl && fix_install_name MacOS/Wish Tk
ifeq (${INSTALL_BUILD},1)
	@cd "${TOP_DIR}" && rm -rf "./${FMWK_DIR}"/T{cl,k}.framework && rmdir -p "./${FMWK_DIR}" 2>&- || true
endif # install not subframework
endif
endif
endif
endif # embedded
endif # not subframework
endif # not X11

clean-${PROJECT}: %-${PROJECT}:
	${DO_MAKE}
	rm -rf "${SYMROOT}"/{${PRODUCT_NAME}.framework,${WISH},tktest}
	rm -f "${OBJ_DIR}"{"${LIBDIR}","${BINDIR}"} && \
	rmdir -p "${OBJ_DIR}"$(dir $(subst ${space},\ ,${LIBDIR})) 2>&- || true && \
	rmdir -p "${OBJ_DIR}"$(dir $(subst ${space},\ ,${BINDIR})) 2>&- || true

Changes to macosx/README.

268
269
270
271
272
273
274

275
276
277
278












279
280
281
282
283
284
285
286
287
288





289
290
291
292
293
294
295
268
269
270
271
272
273
274
275




276
277
278
279
280
281
282
283
284
285
286
287










288
289
290
291
292
293
294
295
296
297
298
299







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







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

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
Tk now provides the following semantic colors as system colors:
systemTextColor, systemTextBackgroundColor, systemSelectedTextColor,
systemSelectedTextBackgroundColor, systemControlTextColor,
systemDisabledControlTextColor, systemLabelColor, systemLinkColor, and
these colors change appearance.  For example systemTextColor is dark in
Aqua and light in DarkAqua.

Tk now provides colors corresponding to all of the NSColors in Apple's System
ColorList.  The convention for naming these colors is that the Tk name is
generated by capitalizing the macOS name and adding the prefix "system". The
System ColorList differs between releases of macOS and some colors, such as
systemLinkColor and systemControlAccentColor, are simulated on older systems
which did not provide them.  The following colors are available on all
supported macOS releases, although newer systems will support additional
colors: systemControlAccentColor, systemControlTextColor,
systemDisabledControlTextColor, systemLabelColor, systemLinkColor,
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.
systemPlaceholderTextColor, systemSelectedTextBackgroundColor,
systemSelectedTextColor, systemSeparatorColor, systemTextBackgroundColor, and
systemTextColor.  One additional color, systemSelectedTabTextColor, does not
exist in macOS but is used by Tk to match the different colors used for
Notebook tab titles in different OS versions.

The default background and foreground colors of most of the Tk widgets
have been set to semantic colors, which means that the widgets will change
appearance, and remain usable, when Dark Mode is selected in the system
preferences.  However, to get a close match to the native Dark Mode style it
is recommended to use Ttk widgets when possible.

450
451
452
453
454
455
456














457
458
459
460
461
462
463
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481







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







If you used non-default install locations for Tcl.framework, specify them as
make overrides to the tk/macosx GNUmakefile, e.g.
	make -C tk${ver}/macosx \
	    TCL_FRAMEWORK_DIR=$HOME/Library/Frameworks TCLSH_DIR=$HOME/usr/bin
	sudo make -C tk${ver}/macosx install \
	    TCL_FRAMEWORK_DIR=$HOME/Library/Frameworks TCLSH_DIR=$HOME/usr/bin
The Makefile variables TCL_FRAMEWORK_DIR and TCLSH_DIR were added with Tk 8.4.3.

- To build a Tcl.framework and Tk.framework for use as subframeworks in another
framework, use the install-embedded target and set SUBFRAMEWORK=1.  Set the
DYLIB_INSTALL_DIR variable to the path which should be the install_name path of
the shared library and set the DESTDIR variable to the pathname of a staging
directory where the frameworks will be written.  The Tcl framework must be
built first.
For example, running the commands:
	make -C ../tcl8.6/macosx install-embedded SUBFRAMEWORK=1 DESTDIR=/tmp/tcltk \
	DYLIB_INSTALL_DIR=/Library/Frameworks/Some.framework/Versions/X.Y/Frameworks/Tcl.framework
	make -C macosx install-embedded SUBFRAMEWORK=1 DESTDIR=/tmp/tcltk \
	DYLIB_INSTALL_DIR=/Library/Frameworks/Some.framework/Versions/X.Y/Frameworks/Tk.framework
will produce a Tcl.framework and a Tk.framework usable as subframeworks of
Some.framework.  The frameworks will be found in /tmp/tcltk/Frameworks/

5. Details regarding the macOS port of Tk.
-------------------------------------------

5.1 About the event loop
~~~~~~~~~~~~~~~~~~~~~~~~

658
659
660
661
662
663
664
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
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718







-
-
+
+

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







inefficient to iterate through all embedded windows in a Text widget,
looking for those which meet the scrolling area, the damage region
constructed by TkScrollWindow contains only the difference between the
source and destination rectangles for the scrolling.  The embedded
windows are redrawn within the DisplayText function by some
conditional code which is only used for macOS.

6.0 Virtual events on 10.14
~~~~~~~~~~~~~~~~~~~~~~~~~~~
6.0 Virtual events on macOS 10.14 and later
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

10.14 supports system appearance changes, and has added a "Dark Mode"
that casts all window frames and menus as black. Tk 8.6.9 has added two
virtual events, <<LightAqua>> and <<DarkAqua>>, to allow you to update
your Tk app's appearance when the system appearance changes. Just bind
your appearance-updating code to these virtual events and you will see
it triggered when the system appearance toggles between dark and light.
The 10.14 release added support for system appearance changes,
including a "Dark Mode" that renders all window frames and menus in
dark colors. Tk 8.6.11 provides three virtual events <<LightAqua>>,
<<DarkAqua>> and <<AppearanceChanged>>, to allow you to update your Tk
app's appearance when the system appearance changes.  These events are
generated in [NSView effectiveAppearanceChanged], which is called by
the Apple window manager when the General Preferences is changed
either by switching between Light Mode and Dark Mode or by changing
the Accent Color or Highlight Color.

The <<AppearanceChanged>> virtual event has a data string which can be
accessed with the %d substitution.  The format of the data string is
that it consists of 6 words:
  "Appearance XXXX Accent YYYY Highlight ZZZZ"
For example, the following code will print the current appearance
name, accent color and highlight color when the <<AppearanceChanged>>
virtual event fires:

bind . <<AppearanceChanged>> {
    array set data [split %d]
    puts "  Appearance: $data(Appearance)"
    puts "  Accent: $data(Accent)"
    puts "  Highlight: $data(Highlight)\n"
}



7.0 Mac Services
~~~~~~~~~~~~~~~~~~~~~~~~~~~

With 8.6.10, Tk supports the Mac's NSServices API, documented at
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/SysServices/introduction.html#//apple_ref/doc/uid/10000101-SW1
and in TIP 536 and Tk's man page. Tk presents a simple,

Changes to macosx/Tk-Common.xcconfig.

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







-
+







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 -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-value -Winit-self -Wpointer-arith -Wcast-align -Wdisabled-optimization -Winline $(WARNING_CFLAGS)
WARNING_CFLAGS = -Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith -Winit-self -Wcast-align -Wdisabled-optimization -Winline $(WARNING_CFLAGS)
REZ_RESOURCE_MAP_READ_ONLY = YES
APPLICATION_INSTALL_PATH = /Applications/Utilities
BINDIR = $(PREFIX)/bin
CFLAGS = $(CFLAGS)
CPPFLAGS = -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET) $(CPPFLAGS)
FRAMEWORK_INSTALL_PATH = /Library/Frameworks
INCLUDEDIR = $(PREFIX)/include

Changes to macosx/Tk.xcode/project.pbxproj.

1404
1405
1406
1407
1408
1409
1410
1411

1412
1413
1414
1415
1416
1417
1418
1404
1405
1406
1407
1408
1409
1410

1411
1412
1413
1414
1415
1416
1417
1418







-
+







		F96D3E1B08F272A5004A47F5 /* CrtChnlHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtChnlHdlr.3; sourceTree = "<group>"; };
		F96D3E1C08F272A5004A47F5 /* CrtCloseHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCloseHdlr.3; sourceTree = "<group>"; };
		F96D3E1D08F272A5004A47F5 /* CrtCommand.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCommand.3; sourceTree = "<group>"; };
		F96D3E1E08F272A5004A47F5 /* CrtFileHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtFileHdlr.3; sourceTree = "<group>"; };
		F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtInterp.3; sourceTree = "<group>"; };
		F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtMathFnc.3; sourceTree = "<group>"; };
		F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtObjCmd.3; sourceTree = "<group>"; };
		F96D3E2208F272A5004A47F5 /* CrtSlave.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtSlave.3; sourceTree = "<group>"; };
		F96D3E2208F272A5004A47F5 /* CrtAlias.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtAlias.3; sourceTree = "<group>"; };
		F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTimerHdlr.3; sourceTree = "<group>"; };
		F96D3E2408F272A5004A47F5 /* CrtTrace.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTrace.3; sourceTree = "<group>"; };
		F96D3E2508F272A5004A47F5 /* dde.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dde.n; sourceTree = "<group>"; };
		F96D3E2608F272A5004A47F5 /* DetachPids.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DetachPids.3; sourceTree = "<group>"; };
		F96D3E2708F272A5004A47F5 /* dict.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dict.n; sourceTree = "<group>"; };
		F96D3E2808F272A5004A47F5 /* DictObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DictObj.3; sourceTree = "<group>"; };
		F96D3E2908F272A5004A47F5 /* DoOneEvent.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoOneEvent.3; sourceTree = "<group>"; };
3069
3070
3071
3072
3073
3074
3075
3076

3077
3078
3079
3080
3081
3082
3083
3069
3070
3071
3072
3073
3074
3075

3076
3077
3078
3079
3080
3081
3082
3083







-
+







				F96D3E1B08F272A5004A47F5 /* CrtChnlHdlr.3 */,
				F96D3E1C08F272A5004A47F5 /* CrtCloseHdlr.3 */,
				F96D3E1D08F272A5004A47F5 /* CrtCommand.3 */,
				F96D3E1E08F272A5004A47F5 /* CrtFileHdlr.3 */,
				F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */,
				F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */,
				F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */,
				F96D3E2208F272A5004A47F5 /* CrtSlave.3 */,
				F96D3E2208F272A5004A47F5 /* CrtAlias.3 */,
				F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */,
				F96D3E2408F272A5004A47F5 /* CrtTrace.3 */,
				F96D3E2508F272A5004A47F5 /* dde.n */,
				F93599D30DF1F8F500E04F67 /* define.n */,
				F96D3E2608F272A5004A47F5 /* DetachPids.3 */,
				F96D3E2708F272A5004A47F5 /* dict.n */,
				F96D3E2808F272A5004A47F5 /* DictObj.3 */,

Changes to macosx/Tk.xcodeproj/project.pbxproj.

1404
1405
1406
1407
1408
1409
1410
1411

1412
1413
1414
1415
1416
1417
1418
1404
1405
1406
1407
1408
1409
1410

1411
1412
1413
1414
1415
1416
1417
1418







-
+







		F96D3E1B08F272A5004A47F5 /* CrtChnlHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtChnlHdlr.3; sourceTree = "<group>"; };
		F96D3E1C08F272A5004A47F5 /* CrtCloseHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCloseHdlr.3; sourceTree = "<group>"; };
		F96D3E1D08F272A5004A47F5 /* CrtCommand.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCommand.3; sourceTree = "<group>"; };
		F96D3E1E08F272A5004A47F5 /* CrtFileHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtFileHdlr.3; sourceTree = "<group>"; };
		F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtInterp.3; sourceTree = "<group>"; };
		F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtMathFnc.3; sourceTree = "<group>"; };
		F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtObjCmd.3; sourceTree = "<group>"; };
		F96D3E2208F272A5004A47F5 /* CrtSlave.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtSlave.3; sourceTree = "<group>"; };
		F96D3E2208F272A5004A47F5 /* CrtAlias.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtAlias.3; sourceTree = "<group>"; };
		F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTimerHdlr.3; sourceTree = "<group>"; };
		F96D3E2408F272A5004A47F5 /* CrtTrace.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTrace.3; sourceTree = "<group>"; };
		F96D3E2508F272A5004A47F5 /* dde.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dde.n; sourceTree = "<group>"; };
		F96D3E2608F272A5004A47F5 /* DetachPids.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DetachPids.3; sourceTree = "<group>"; };
		F96D3E2708F272A5004A47F5 /* dict.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dict.n; sourceTree = "<group>"; };
		F96D3E2808F272A5004A47F5 /* DictObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DictObj.3; sourceTree = "<group>"; };
		F96D3E2908F272A5004A47F5 /* DoOneEvent.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoOneEvent.3; sourceTree = "<group>"; };
3068
3069
3070
3071
3072
3073
3074
3075

3076
3077
3078
3079
3080
3081
3082
3068
3069
3070
3071
3072
3073
3074

3075
3076
3077
3078
3079
3080
3081
3082







-
+







				F96D3E1B08F272A5004A47F5 /* CrtChnlHdlr.3 */,
				F96D3E1C08F272A5004A47F5 /* CrtCloseHdlr.3 */,
				F96D3E1D08F272A5004A47F5 /* CrtCommand.3 */,
				F96D3E1E08F272A5004A47F5 /* CrtFileHdlr.3 */,
				F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */,
				F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */,
				F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */,
				F96D3E2208F272A5004A47F5 /* CrtSlave.3 */,
				F96D3E2208F272A5004A47F5 /* CrtAlias.3 */,
				F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */,
				F96D3E2408F272A5004A47F5 /* CrtTrace.3 */,
				F96D3E2508F272A5004A47F5 /* dde.n */,
				F93599D30DF1F8F500E04F67 /* define.n */,
				F96D3E2608F272A5004A47F5 /* DetachPids.3 */,
				F96D3E2708F272A5004A47F5 /* dict.n */,
				F96D3E2808F272A5004A47F5 /* DictObj.3 */,

Changes to macosx/tkMacOSX.h.

22
23
24
25
26
27
28
29

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

29
30
31
32
33
34







-
+





 * Structures and function types for handling Netscape-type in process
 * embedding where Tk does not control the top-level
 */

typedef int (Tk_MacOSXEmbedRegisterWinProc) (long winID, Tk_Window window);
typedef void* (Tk_MacOSXEmbedGetGrafPortProc) (Tk_Window window);
typedef int (Tk_MacOSXEmbedMakeContainerExistProc) (Tk_Window window);
typedef void (Tk_MacOSXEmbedGetClipProc) (Tk_Window window, Region rgn);
typedef void (Tk_MacOSXEmbedGetClipProc) (Tk_Window window, void *rgn);
typedef void (Tk_MacOSXEmbedGetOffsetInParentProc) (Tk_Window window, void *ulCorner);

#include "tkPlatDecls.h"

#endif /* _TKMAC */

Changes to macosx/tkMacOSXBitmap.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





-
-
-
+
+
+







/*
 * 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 <[email protected]>
 * Copyright © 1996-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2006-2009 Daniel A. Steffen <[email protected]>
 *
 * 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"
132
133
134
135
136
137
138
139

140
141
142
143
144
145

146
147
148
149
150
151
152
153
154
132
133
134
135
136
137
138

139
140
141
142
143
144

145


146
147
148
149
150
151
152







-
+





-
+
-
-







    NSImage* image,
    CGSize size)
{
    TkMacOSXDrawingContext dc;
    Pixmap pixmap;

    pixmap = Tk_GetPixmap(display, None, size.width, size.height, 0);
    if (TkMacOSXSetupDrawingContext(pixmap, NULL, 1, &dc)) {
    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:[NSGraphicsContext
	    [NSGraphicsContext setCurrentContext:GET_NSCONTEXT(dc.context, NO)];
		graphicsContextWithGraphicsPort:dc.context
		flipped:NO]];
	    [image drawAtPoint:NSZeroPoint fromRect:NSZeroRect
		operation:NSCompositeCopy fraction:1.0];
	    [NSGraphicsContext restoreGraphicsState];
	}
	TkMacOSXRestoreDrawingContext(&dc);
    }
    return pixmap;
176
177
178
179
180
181
182
183

184
185
186
187
188
189
190
174
175
176
177
178
179
180

181
182
183
184
185
186
187
188







-
+







    Display *display,
    const void *source)		/* Info about the icon to build. */
{
    NSString *iconUTI = OSTYPE_TO_UTI(PTR2UINT(source));
    NSImage *iconImage = [[NSWorkspace sharedWorkspace]
			     iconForFileType: iconUTI];
    CGSize size = CGSizeMake(builtInIconSize, builtInIconSize);
    Pixmap pixmap = PixmapFromImage(display, iconImage, NSSizeToCGSize(size));
    Pixmap pixmap = PixmapFromImage(display, iconImage, size);
    return pixmap;
}


/*
 *----------------------------------------------------------------------
 *
339
340
341
342
343
344
345
346

347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
337
338
339
340
341
342
343

344
345
346
347
348
349
350
351
352

353
354
355
356
357
358
359







-
+








-







 *	none
 *
 *----------------------------------------------------------------------
 */

int
TkMacOSXIconBitmapObjCmd(
    ClientData dummy,	/* Unused. */
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tcl_HashEntry *hPtr;
    int i = 1, len, isNew, result = TCL_ERROR;
    const char *name, *value;
    IconBitmap ib, *iconBitmap;
    (void)dummy;

    if (objc != 6) {
	Tcl_WrongNumArgs(interp, 1, objv, "name width height "
		"-file|-fileType|-osType|-systemType|-namedImage|-imageFile "
		"value");
	goto end;
    }

Changes to macosx/tkMacOSXButton.c.

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






13
14
15
16
17
18
19
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 <[email protected]>
 * 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 <[email protected]>
 * 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"
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
190
191
192
193
194
195
196







197
198
199
200
201
202
203







-
-
-
-
-
-
-








    butPtr->flags &= ~REDRAW_PENDING;
    if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
    }
    pixmap = (Pixmap) Tk_WindowId(tkwin);

    /*
     * Set up clipping region. Make sure the we are using the port
     * for this button, or we will set the wrong window's clip.
     */

    TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin));

    if (TkMacOSXComputeButtonDrawParams(butPtr, dpPtr)) {
	macButtonPtr->useTkText = 0;
    } else {
	macButtonPtr->useTkText = 1;
    }
    if (macButtonPtr->useTkText) {
	if (butPtr->type == TYPE_BUTTON) {
722
723
724
725
726
727
728
729

730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755

756
757
758
759
760
761
762
715
716
717
718
719
720
721

722
723
724
725
726
727
728
729
730
731
732

733
734
735
736
737
738
739
740
741
742
743
744
745
746

747
748
749
750
751
752
753
754







-
+










-














-
+







 *
 *--------------------------------------------------------------
 */

static void
TkMacOSXDrawButton(
    MacButton *mbPtr,    /* Mac button. */
    GC gc,               /* The GC we are drawing into - needed for
    TCL_UNUSED(GC),      /* The GC we are drawing into - needed for
                          * the bevel button */
    Pixmap pixmap)       /* The pixmap we are drawing into - needed
                          * for the bevel button */
{
    TkButton *butPtr = (TkButton *) mbPtr;
    TkWindow *winPtr = (TkWindow *) butPtr->tkwin;
    HIRect cntrRect;
    TkMacOSXDrawingContext dc;
    DrawParams *dpPtr = &mbPtr->drawParams;
    int useNewerHITools = 1;
    (void)gc;

    TkMacOSXComputeButtonParams(butPtr, &mbPtr->btnkind, &mbPtr->drawinfo);

    cntrRect = CGRectMake(winPtr->privatePtr->xOff, winPtr->privatePtr->yOff,
	    Tk_Width(butPtr->tkwin), Tk_Height(butPtr->tkwin));

    cntrRect = CGRectInset(cntrRect, butPtr->inset, butPtr->inset);

    if (useNewerHITools == 1) {
        HIRect contHIRec;
        static HIThemeButtonDrawInfo hiinfo;

        ButtonBackgroundDrawCB(&cntrRect, mbPtr, 32, true);

	if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, 1, &dc)) {
	if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, &dc)) {
	    return;
	}

        hiinfo.version = 0;
        hiinfo.state = mbPtr->drawinfo.state;
        hiinfo.kind = mbPtr->btnkind;
        hiinfo.value = mbPtr->drawinfo.value;
781
782
783
784
785
786
787
788

789
790
791
792
793
794
795
773
774
775
776
777
778
779

780
781
782
783
784
785
786
787







-
+







	HIThemeDrawButton(&cntrRect, &hiinfo, dc.context,
		kHIThemeOrientationNormal, &contHIRec);

	TkMacOSXRestoreDrawingContext(&dc);
        ButtonContentDrawCB(&contHIRec, mbPtr->btnkind, &mbPtr->drawinfo,
		(MacButton *) mbPtr, 32, true);
    } else {
	if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, 1, &dc)) {
	if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, &dc)) {
	    return;
	}

	TkMacOSXRestoreDrawingContext(&dc);
    }
    mbPtr->lastdrawinfo = mbPtr->drawinfo;
}
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
801
802
803
804
805
806
807

808
809


810
811
812
813
814
815
816
817



818
819
820
821
822
823
824







-
+

-
-
+
+






-
-
-







 *        The background gets updated to the current color.
 *
 *--------------------------------------------------------------
 */

static void
ButtonBackgroundDrawCB(
    const HIRect *btnbounds,
    TCL_UNUSED(const HIRect *),
    MacButton *ptr,
    SInt16 depth,
    Boolean isColorDev)
    TCL_UNUSED(SInt16),
    TCL_UNUSED(Boolean))
{
    MacButton *mbPtr = (MacButton *) ptr;
    TkButton *butPtr = (TkButton *) mbPtr;
    Tk_Window tkwin = butPtr->tkwin;
    Pixmap pixmap;
    int usehlborder = 0;
    (void)btnbounds;
    (void)depth;
    (void)isColorDev;

    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
        return;
    }
    pixmap = (Pixmap) Tk_WindowId(tkwin);

    if (butPtr->type != TYPE_LABEL) {
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
853
854
855
856
857
858
859



860
861
862
863


864
865
866
867
868





869
870
871
872
873
874
875







-
-
-
+
+
+

-
-
+
+



-
-
-
-
-







 * Side effects:
 *        The content of the button gets updated.
 *
 *--------------------------------------------------------------
 */
static void
ButtonContentDrawCB (
    const HIRect * btnbounds,
    ThemeButtonKind kind,
    const HIThemeButtonDrawInfo *drawinfo,
    TCL_UNUSED(const HIRect *),
    TCL_UNUSED(ThemeButtonKind),
    TCL_UNUSED(const HIThemeButtonDrawInfo *),
    MacButton *ptr,
    SInt16 depth,
    Boolean isColorDev)
    TCL_UNUSED(SInt16),
    TCL_UNUSED(Boolean))
{
    TkButton *butPtr = (TkButton *) ptr;
    Tk_Window tkwin = butPtr->tkwin;
    (void)btnbounds;
    (void)kind;
    (void)drawinfo;
    (void)depth;
    (void)isColorDev;

    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
        return;
    }

    /*
     * Overlay Tk elements over button native region: drawing elements within

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 <[email protected]>
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2006-2009 Daniel A. Steffen <[email protected]>
 *
 * 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"
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







-
+







 */

int
XSetSelectionOwner(
    Display *display,		/* X Display. */
    Atom selection,		/* What selection to own. */
    Window owner,		/* Window to be the owner. */
    Time time)			/* The current time? */
    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) {
234
235
236
237
238
239
240
241
242


243
244
245
246
247
248
249
250
251
252
253
254
234
235
236
237
238
239
240


241
242
243
244
245


246
247
248
249
250
251
252







-
-
+
+



-
-







 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkSelUpdateClipboard(
    TkWindow *winPtr,		/* Window associated with clipboard. */
    TkClipboardTarget *targetPtr)
    TCL_UNUSED(TkWindow *),		/* Window associated with clipboard. */
    TCL_UNUSED(TkClipboardTarget *))
				/* Info about the content. */
{
    NSPasteboard *pb = [NSPasteboard generalPasteboard];
    (void)winPtr;
    (void)targetPtr;

    changeCount = [pb addTypes:[NSArray arrayWithObject:NSStringPboardType]
	    owner:NSApp];
}

/*
 *--------------------------------------------------------------
293
294
295
296
297
298
299
300

301
302
303
304
305
306
307
308
309
310
311
312
291
292
293
294
295
296
297

298
299

300
301
302
303
304
305
306
307
308
309







-
+

-










 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkSelPropProc(
    XEvent *eventPtr)	/* X PropertyChange event. */
    TCL_UNUSED(XEvent *))	/* X PropertyChange event. */
{
    (void)eventPtr;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXColor.c.

1
2

3
4
5
6
7
8
9
10
11





12
13
14
15
16
17
18

19
20
21
22
23
24















25
26
27
28
29
30















31
32
33
34
35
36


37
38
39
40




41


42
43
44
45












46
47

48
49









50
51
52
53
54
55






56
57
58
59
60
61
62
63
64
65
66
67











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






83
84
85
86
87
88
89
90
91
92
93











94
95


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













114
115


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
















141
142
143
144
145
146
147
148
149
150
151
152
153




154
155


156
157
158
159
160





161
162
163



164
165
166



167
168
169
170
171
172
173
174
175
176
177











178
179
180
181
182
183








184
185
186
187
188
189
190
191
192
193
194
195
196























197
198
199
200
201
202
203
204
205
206
207
208
209
210
211






212
213
214
215
216
217
218
219
220
221
222
223
224
225

226
227


228
229
230


231
232
233

234
235
236
237
238
239
240



241
242


243
244
245







246
247

248
249
250




251
252
253
254

255


256
257


258
259

260
261
262

263
264
265

266
267
268
269
270
271
272
273
274
275
276



277
278

279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295

296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313


314
315
316
317
318
319
320
321

322
323
324
325

326
327
328
329
330
331

332
333
334

335
336

337
338
339
340
341
342
343
344
345
346
347



348
349
350
351
352
353
354







355
356
357

358
359
360
361
362
363






364
365
366

367
368
369


370
371
372
373
374
375
376
377
378

379
380







381
382
383
384
385






386
387
388
389


390
391
392
393




394
395
396
397


398
399

400
401
402





403
404
405
406

407
408

409
410

411
412


413
414


415

416
417
418

419
420
421
422
423
424
425
1

2
3
4
5
6
7




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





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






37
38
39
40
41
42
43
44
45
46
47
48
49
50
51






52
53
54



55
56
57
58
59
60
61




62
63
64
65
66
67
68
69
70
71
72
73


74


75
76
77
78
79
80
81
82
83






84
85
86
87
88
89












90
91
92
93
94
95
96
97
98
99
100















101
102
103
104
105
106











107
108
109
110
111
112
113
114
115
116
117


118
119


















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


133
134

























135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150













151
152
153
154


155
156





157
158
159
160
161



162
163
164



165
166
167











168
169
170
171
172
173
174
175
176
177
178






179
180
181
182
183
184
185
186













187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209















210
211
212
213
214
215









216
217
218
219

220
221

222
223
224
225

226
227
228
229

230
231
232
233
234



235
236
237

238
239
240



241
242
243
244
245
246
247
248

249



250
251
252
253
254
255
256

257
258
259
260


261
262


263
264
265

266
267
268

269
270
271
272
273







274
275
276
277

278
279

280

281
282
283
284
285








286



287
288
289
290
291
292
293
294
295
296
297
298
299


300
301
302
303
304
305
306
307
308

309
310
311
312

313
314
315
316



317



318


319











320
321
322







323
324
325
326
327
328
329
330
331

332
333





334
335
336
337
338
339



340



341
342









343


344
345
346
347
348
349
350





351
352
353
354
355
356




357
358




359
360
361
362




363
364


365



366
367
368
369
370

371
372

373


374
375
376
377


378
379


380
381
382
383
384
385

386
387
388
389
390
391
392
393

-
+





-
-
-
-
+
+
+
+
+







+

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

-
-
-
+
+
+
+

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




-
+

-
+
+


-
+
+


-
+




-
-
-
+
+
+
-

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

-
+
-
-
-
+
+
+
+



-
+

+
+
-
-
+
+
-
-
+


-
+


-
+




-
-
-
-
-
-
-
+
+
+

-
+

-

-





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













-
-
+
+







-
+



-
+



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


-
+

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


-
+
-
-
+


+
-
-
+
+
-
-
+
+

+


-
+







/*
 * tkMacOSXColor.c --
 * 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 <[email protected]>
 * 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 <[email protected]>
 * 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"

/*
 * The colorType specifies how the color value should be interpreted.  For the
 * unique rgbColor entry, the RGB values are generated from the pixel value of
 * an XColor.  The ttkBackground and semantic types are dynamic, meaning
 * that they change when dark mode is enabled on OSX 10.13 and later.
static Tcl_HashTable systemColors;
static int numSystemColors;
static int rgbColorIndex;
static int controlAccentIndex;
static int selectedTabTextIndex;
static Bool useFakeAccentColor = NO;
static SystemColorDatum **systemColorIndex;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
static NSAppearance *lightAqua = nil;
static NSAppearance *darkAqua = nil;
#endif
static NSColorSpace* sRGB = NULL;
static const CGFloat WINDOWBACKGROUND[4] =
    {236.0 / 255, 236.0 / 255, 236.0 / 255, 1.0};

 */

enum colorType {
    clearColor,    /* There should be only one of these. */
    rgbColor,      /* There should be only one of these. */
    appearance,    /* There should be only one of these. */
void initColorTable()
{
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    Tcl_InitHashTable(&systemColors, TCL_STRING_KEYS);
    SystemColorDatum *entry, *oldEntry;
    Tcl_HashSearch search;
    Tcl_HashEntry *hPtr;
    int newPtr, index = 0;
    NSColorList *systemColorList = [NSColorList colorListNamed:@"System"];
    NSString *key;

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
    if (@available(macOS 10.14, *)) {
	darkAqua = [NSAppearance appearanceNamed:NSAppearanceNameDarkAqua];
        lightAqua = [NSAppearance appearanceNamed:NSAppearanceNameAqua];
    HIBrush,       /* The value is a HITheme brush color table index. */
    HIText,        /* The value is a HITheme text color table index. */
    HIBackground,  /* The value is a HITheme background color table index. */
    ttkBackground, /* The value can be used as a parameter.*/
    semantic, /* The value can be used as a parameter.*/
};
    }
#endif

/*

 */
    /*
     * Build a hash table for looking up a color by its name.
     * First add all of the static entries from tkMacOSXColor.h
     */

    for (entry = systemColorData; entry->name != NULL; entry++) {
	hPtr = Tcl_CreateHashEntry(&systemColors, entry->name, &newPtr);
struct SystemColorMapEntry {
    const char *name;
    enum colorType type;
    long value;
	if (entry->type == semantic) {
	    NSString *colorName = [[NSString alloc]
				   initWithCString:entry->macName
					  encoding:NSUTF8StringEncoding];
	    SEL colorSelector = NSSelectorFromString(colorName);
	    if (![NSColor respondsToSelector:colorSelector]) {
		if ([colorName isEqualToString:@"controlAccentColor"]) {
		    useFakeAccentColor = YES;
		} else if (![colorName isEqualToString:@"selectedTabTextColor"]) {
		    /* Uncomment to print all unsupported colors:              */
		    /* printf("Unsupported color %s\n", colorName.UTF8String); */
		    continue;
};  /* unsigned char pixelCode; */

		}
/*
 * Array of system color definitions: the array index is required to equal the
	    }
	    entry->selector = [colorName retain];
	}
	if (newPtr == 0) {
	    oldEntry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
	    entry->index = oldEntry->index;
	    [oldEntry->selector release];
	} else {
	    entry->index = index++;
 * color's (pixelCode - MIN_PIXELCODE), i.e. the array order needs to be kept
 * in sync with the public pixel code values in tkMacOSXPort.h !
 */

#define MIN_PIXELCODE  30
static const struct SystemColorMapEntry systemColorMap[] = {
	}
	Tcl_SetHashValue(hPtr, entry);
    }

    /*
     * Add all of the colors in the System ColorList.
    { "Transparent",			    clearColor,   0 },						    /*  30: TRANSPARENT_PIXEL */
    { "Highlight",			    HIBrush,      kThemeBrushPrimaryHighlightColor },		    /*  31 */
    { "HighlightSecondary",		    HIBrush,      kThemeBrushSecondaryHighlightColor },		    /*  32 */
    { "HighlightText",			    HIBrush,      kThemeBrushBlack },				    /*  33 */
    { "HighlightAlternate",		    HIBrush,      kThemeBrushAlternatePrimaryHighlightColor },	    /*  34 */
    { "ButtonText",			    HIText,       kThemeTextColorPushButtonActive },	       	    /*  35 */
    { "PrimaryHighlightColor",		    HIBrush,      kThemeBrushPrimaryHighlightColor },		    /*  36 */
    { "ButtonFace",			    HIBrush,      kThemeBrushButtonFaceActive },	       	    /*  37 */
    { "SecondaryHighlightColor",	    HIBrush,      kThemeBrushSecondaryHighlightColor },		    /*  38 */
    { "ButtonFrame",			    HIBrush,      kThemeBrushButtonFrameActive },	       	    /*  39 */
    { "AlternatePrimaryHighlightColor",	    HIBrush,      kThemeBrushAlternatePrimaryHighlightColor },	    /*  40 */
    { "WindowBody",			    HIBrush,      kThemeBrushDocumentWindowBackground },       	    /*  41 */
     */

    for (key in [systemColorList allKeys]) {
	int length = [key lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
	char *name;
	entry = (SystemColorDatum *)ckalloc(sizeof(SystemColorDatum));
	bzero(entry, sizeof(SystemColorDatum));
	name = (char *)ckalloc(length + 1);
	strcpy(name, key.UTF8String);
	name[0] = toupper(name[0]);
        if (!strcmp(name, "WindowBackgroundColor")) {
    { "SheetBackground",		    HIBrush,      kThemeBrushSheetBackground },			    /*  42 */
    { "MenuActive",			    HIBrush,      kThemeBrushMenuBackgroundSelected },		    /*  43 */
    { "Black",				    HIBrush,      kThemeBrushBlack },				    /*  44 */
    { "MenuActiveText",			    HIText,       kThemeTextColorMenuItemSelected },	       	    /*  45 */
    { "White",				    HIBrush,      kThemeBrushWhite },				    /*  46 */
    { "Menu",				    HIBrush,      kThemeBrushMenuBackground },			    /*  47 */
    { "DialogBackgroundActive",		    HIBrush,      kThemeBrushDialogBackgroundActive },		    /*  48 */
    { "MenuDisabled",			    HIText,       kThemeTextColorMenuItemDisabled },	       	    /*  49 */
    { "DialogBackgroundInactive",	    HIBrush,      kThemeBrushDialogBackgroundInactive },       	    /*  50 */
    { "MenuText",			    HIText,       kThemeTextColorMenuItemActive },	       	    /*  51 */
    { "AppearanceColor",		    appearance,   0 },						    /*  52: APPEARANCE_PIXEL */
    { "AlertBackgroundActive",		    HIBrush,      kThemeBrushAlertBackgroundActive },		    /*  53 */
    { "AlertBackgroundInactive",	    HIBrush,      kThemeBrushAlertBackgroundInactive },		    /*  54 */
    { "ModelessDialogBackgroundActive",	    HIBrush,      kThemeBrushModelessDialogBackgroundActive },	    /*  55 */
    { "ModelessDialogBackgroundInactive",   HIBrush,      kThemeBrushModelessDialogBackgroundInactive },    /*  56 */

	    /*
	     * Avoid black windows on old systems.
	     */

	    continue;
    { "UtilityWindowBackgroundActive",	    HIBrush,      kThemeBrushUtilityWindowBackgroundActive },	    /*  57 */
    { "UtilityWindowBackgroundInactive",    HIBrush,      kThemeBrushUtilityWindowBackgroundInactive },	    /*  58 */
    { "ListViewSortColumnBackground",	    HIBrush,      kThemeBrushListViewSortColumnBackground },	    /*  59 */
    { "ListViewBackground",		    HIBrush,      kThemeBrushListViewBackground },	       	    /*  60 */
    { "IconLabelBackground",		    HIBrush,      kThemeBrushIconLabelBackground },    		    /*  61 */
    { "ListViewSeparator",		    HIBrush,      kThemeBrushListViewSeparator },      		    /*  62 */
    { "ChasingArrows",			    HIBrush,      kThemeBrushChasingArrows },			    /*  63 */
    { "DragHilite",			    HIBrush,      kThemeBrushDragHilite },	       		    /*  64 */
    { "DocumentWindowBackground",	    HIBrush,      kThemeBrushDocumentWindowBackground },       	    /*  65 */
    { "FinderWindowBackground",		    HIBrush,      kThemeBrushFinderWindowBackground },		    /*  66 */
    { "ScrollBarDelimiterActive",	    HIBrush,      kThemeBrushScrollBarDelimiterActive },       	    /*  67 */
	}
	entry->type=semantic;
	entry->name = name;
	entry->selector = [key retain];
	hPtr = Tcl_CreateHashEntry(&systemColors, entry->name, &newPtr);
	if (newPtr == 0) {
	    oldEntry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
	    entry->index = oldEntry->index;
	    [oldEntry->selector release];
	} else {
	    entry->index = index++;
    { "ScrollBarDelimiterInactive",	    HIBrush,      kThemeBrushScrollBarDelimiterInactive },     	    /*  68 */
    { "FocusHighlight",			    HIBrush,      kThemeBrushFocusHighlight },			    /*  69 */
	}
	Tcl_SetHashValue(hPtr, entry);
    { "PopupArrowActive",		    HIBrush,      kThemeBrushPopupArrowActive },	       	    /*  70 */
    { "PopupArrowPressed",		    HIBrush,      kThemeBrushPopupArrowPressed },	       	    /*  71 */
    { "PopupArrowInactive",		    HIBrush,      kThemeBrushPopupArrowInactive },	       	    /*  72 */
    { "AppleGuideCoachmark",		    HIBrush,      kThemeBrushAppleGuideCoachmark },	       	    /*  73 */
    { "IconLabelBackgroundSelected",	    HIBrush,      kThemeBrushIconLabelBackgroundSelected },    	    /*  74 */
    { "StaticAreaFill",			    HIBrush,      kThemeBrushStaticAreaFill },			    /*  75 */
    { "ActiveAreaFill",			    HIBrush,      kThemeBrushActiveAreaFill },			    /*  76 */
    { "ButtonFrameActive",		    HIBrush,      kThemeBrushButtonFrameActive },		    /*  77 */
    { "ButtonFrameInactive",		    HIBrush,      kThemeBrushButtonFrameInactive },	       	    /*  78 */
    { "ButtonFaceActive",		    HIBrush,      kThemeBrushButtonFaceActive },       		    /*  79 */
    { "ButtonFaceInactive",		    HIBrush,      kThemeBrushButtonFaceInactive },	       	    /*  80 */
    { "ButtonFacePressed",		    HIBrush,      kThemeBrushButtonFacePressed },	       	    /*  81 */
    { "ButtonActiveDarkShadow",		    HIBrush,      kThemeBrushButtonActiveDarkShadow },		    /*  82 */
    { "ButtonActiveDarkHighlight",	    HIBrush,      kThemeBrushButtonActiveDarkHighlight },	    /*  83 */
    { "ButtonActiveLightShadow",	    HIBrush,      kThemeBrushButtonActiveLightShadow },		    /*  84 */
    { "ButtonActiveLightHighlight",	    HIBrush,      kThemeBrushButtonActiveLightHighlight },	    /*  85 */
    { "ButtonInactiveDarkShadow",	    HIBrush,      kThemeBrushButtonInactiveDarkShadow },	    /*  86 */
    { "ButtonInactiveDarkHighlight",	    HIBrush,      kThemeBrushButtonInactiveDarkHighlight },	    /*  87 */
    }

    /*
     * Build an array for looking up a color by its index.
     */

    numSystemColors = index;
    systemColorIndex = (SystemColorDatum **)ckalloc(numSystemColors * sizeof(SystemColorDatum *));
    for (hPtr = Tcl_FirstHashEntry(&systemColors, &search); hPtr != NULL;
	 hPtr = Tcl_NextHashEntry(&search)) {
	entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
	if (entry == NULL) {
	    Tcl_Panic("Unsupported semantic color with no supported backup!");
    { "ButtonInactiveLightShadow",	    HIBrush,      kThemeBrushButtonInactiveLightShadow },	    /*  88 */
    { "ButtonInactiveLightHighlight",	    HIBrush,      kThemeBrushButtonInactiveLightHighlight },	    /*  89 */
	}
	systemColorIndex[entry->index] = entry;
    { "ButtonPressedDarkShadow",	    HIBrush,      kThemeBrushButtonPressedDarkShadow },		    /*  90 */
    { "ButtonPressedDarkHighlight",	    HIBrush,      kThemeBrushButtonPressedDarkHighlight },	    /*  91 */
    { "ButtonPressedLightShadow",	    HIBrush,      kThemeBrushButtonPressedLightShadow },	    /*  92 */
    { "ButtonPressedLightHighlight",	    HIBrush,      kThemeBrushButtonPressedLightHighlight },	    /*  93 */
    { "BevelActiveLight",		    HIBrush,      kThemeBrushBevelActiveLight },		    /*  94 */
    { "BevelActiveDark",		    HIBrush,      kThemeBrushBevelActiveDark },			    /*  95 */
    { "BevelInactiveLight",		    HIBrush,      kThemeBrushBevelInactiveLight },		    /*  96 */
    { "BevelInactiveDark",		    HIBrush,      kThemeBrushBevelInactiveDark },		    /*  97 */
    { "NotificationWindowBackground",	    HIBrush,      kThemeBrushNotificationWindowBackground },	    /*  98 */
    { "MovableModalBackground",		    HIBrush,      kThemeBrushMovableModalBackground },		    /*  99 */
    { "SheetBackgroundOpaque",		    HIBrush,      kThemeBrushSheetBackgroundOpaque },		    /* 100 */
    { "DrawerBackground",		    HIBrush,      kThemeBrushDrawerBackground },		    /* 101 */
    { "ToolbarBackground",		    HIBrush,      kThemeBrushToolbarBackground },		    /* 102 */
    { "SheetBackgroundTransparent",	    HIBrush,      kThemeBrushSheetBackgroundTransparent },	    /* 103 */
    { "MenuBackground",			    HIBrush,      kThemeBrushMenuBackground },			    /* 104 */
    { "Pixel",				    rgbColor,     0 },						    /* 105: PIXEL_MAGIC */
    { "MenuBackgroundSelected",		    HIBrush,      kThemeBrushMenuBackgroundSelected },		    /* 106 */
    { "ListViewOddRowBackground",	    HIBrush,      kThemeBrushListViewOddRowBackground },	    /* 107 */
    { "ListViewEvenRowBackground",	    HIBrush,      kThemeBrushListViewEvenRowBackground },	    /* 108 */
    { "ListViewColumnDivider",		    HIBrush,      kThemeBrushListViewColumnDivider },		    /* 109 */
    { "BlackText",			    HIText,       kThemeTextColorBlack },			    /* 110 */
    { "DialogActiveText",		    HIText,       kThemeTextColorDialogActive },		    /* 111 */
    { "DialogInactiveText",		    HIText,       kThemeTextColorDialogInactive },		    /* 112 */
    { "AlertActiveText",		    HIText,       kThemeTextColorAlertActive },			    /* 113 */
    { "AlertInactiveText",		    HIText,       kThemeTextColorAlertInactive },		    /* 114 */
    }

    /*
     * Remember the indexes of some special entries.
     */

    hPtr = Tcl_FindHashEntry(&systemColors, "Pixel");
    entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
    rgbColorIndex = entry->index;
    hPtr = Tcl_FindHashEntry(&systemColors, "ControlAccentColor");
    entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
    controlAccentIndex = entry->index;
    hPtr = Tcl_FindHashEntry(&systemColors, "SelectedTabTextColor");
    entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
    selectedTabTextIndex = entry->index;
    [pool drain];
    { "ModelessDialogActiveText",	    HIText,       kThemeTextColorModelessDialogActive },	    /* 115 */
    { "ModelessDialogInactiveText",	    HIText,       kThemeTextColorModelessDialogInactive },	    /* 116 */
    { "WindowHeaderActiveText",		    HIText,       kThemeTextColorWindowHeaderActive },		    /* 117 */
    { "WindowHeaderInactiveText",	    HIText,       kThemeTextColorWindowHeaderInactive },	    /* 118 */
    { "PlacardActiveText",		    HIText,       kThemeTextColorPlacardActive },		    /* 119 */
    { "PlacardInactiveText",		    HIText,       kThemeTextColorPlacardInactive },		    /* 120 */
    { "PlacardPressedText",		    HIText,       kThemeTextColorPlacardPressed },		    /* 121 */
    { "PushButtonActiveText",		    HIText,       kThemeTextColorPushButtonActive },		    /* 122 */
    { "PushButtonInactiveText",		    HIText,       kThemeTextColorPushButtonInactive },		    /* 123 */
    { "PushButtonPressedText",		    HIText,       kThemeTextColorPushButtonPressed },		    /* 124 */
    { "BevelButtonActiveText",		    HIText,       kThemeTextColorBevelButtonActive },		    /* 125 */
    { "BevelButtonInactiveText",	    HIText,       kThemeTextColorBevelButtonInactive },		    /* 126 */
    { "BevelButtonPressedText",		    HIText,       kThemeTextColorBevelButtonPressed },		    /* 127 */
}

/*
 *----------------------------------------------------------------------
    { "PopupButtonActiveText",		    HIText,       kThemeTextColorPopupButtonActive },		    /* 128 */
    { "PopupButtonInactiveText",	    HIText,       kThemeTextColorPopupButtonInactive },		    /* 129 */
 *
 * TkMacOSXRGBPixel --
    { "PopupButtonPressedText",		    HIText,       kThemeTextColorPopupButtonPressed },		    /* 130 */
    { "IconLabelText",			    HIText,       kThemeTextColorIconLabel },			    /* 131 */
    { "ListViewText",			    HIText,       kThemeTextColorListView },			    /* 132 */
    { "DocumentWindowTitleActiveText",	    HIText,       kThemeTextColorDocumentWindowTitleActive },	    /* 133 */
    { "DocumentWindowTitleInactiveText",    HIText,       kThemeTextColorDocumentWindowTitleInactive },	    /* 134 */
 *
 *	Return an unsigned long value suitable for use in the pixel
 *	field of an XColor with the specified red, green and blue
 *	intensities.  The inputs are cast as unsigned longs but are
 *      expected to have values representable by an unsigned char.
    { "MovableModalWindowTitleActiveText",  HIText,       kThemeTextColorMovableModalWindowTitleActive },   /* 135 */
    { "MovableModalWindowTitleInactiveText",HIText,       kThemeTextColorMovableModalWindowTitleInactive }, /* 136 */
    { "UtilityWindowTitleActiveText",	    HIText,       kThemeTextColorUtilityWindowTitleActive },	    /* 137 */
 *
 *      This is called in the TkpGetPixel macro, used in xcolor.c,
 *      and in ImageGetPixel.
    { "UtilityWindowTitleInactiveText",	    HIText,       kThemeTextColorUtilityWindowTitleInactive },	    /* 138 */
    { "PopupWindowTitleActiveText",	    HIText,       kThemeTextColorPopupWindowTitleActive },	    /* 139 */
    { "PopupWindowTitleInactiveText",	    HIText,       kThemeTextColorPopupWindowTitleInactive },	    /* 140 */
 *
 * Results:
 *	An unsigned long that can be used as the pixel field of an XColor.
    { "RootMenuActiveText",		    HIText,       kThemeTextColorRootMenuActive },		    /* 141 */
    { "RootMenuSelectedText",		    HIText,       kThemeTextColorRootMenuSelected },		    /* 142 */
    { "RootMenuDisabledText",		    HIText,       kThemeTextColorRootMenuDisabled },		    /* 143 */
    { "MenuItemActiveText",		    HIText,       kThemeTextColorMenuItemActive },		    /* 144 */
    { "MenuItemSelectedText",		    HIText,       kThemeTextColorMenuItemSelected },		    /* 145 */
    { "MenuItemDisabledText",		    HIText,       kThemeTextColorMenuItemDisabled },		    /* 146 */
    { "PopupLabelActiveText",		    HIText,       kThemeTextColorPopupLabelActive },		    /* 147 */
    { "PopupLabelInactiveText",		    HIText,       kThemeTextColorPopupLabelInactive },		    /* 148 */
    { "TabFrontActiveText",		    HIText,       kThemeTextColorTabFrontActive },		    /* 149 */
    { "TabNonFrontActiveText",		    HIText,       kThemeTextColorTabNonFrontActive },		    /* 150 */
    { "TabNonFrontPressedText",		    HIText,       kThemeTextColorTabNonFrontPressed },		    /* 151 */
 *
 * Side effects:
 *	None.
 *----------------------------------------------------------------------
 */
MODULE_SCOPE
unsigned long
TkMacOSXRGBPixel(
    unsigned long red,
    unsigned long green,
    unsigned long blue)
    { "TabFrontInactiveText",		    HIText,       kThemeTextColorTabFrontInactive },		    /* 152 */
    { "TabNonFrontInactiveText",	    HIText,       kThemeTextColorTabNonFrontInactive },		    /* 153 */
    { "IconLabelSelectedText",		    HIText,       kThemeTextColorIconLabelSelected },		    /* 154 */
    { "BevelButtonStickyActiveText",	    HIText,       kThemeTextColorBevelButtonStickyActive },	    /* 155 */
    { "BevelButtonStickyInactiveText",	    HIText,       kThemeTextColorBevelButtonStickyInactive },	    /* 156 */
    { "NotificationText",		    HIText,       kThemeTextColorNotification },		    /* 157 */
{
    MacPixel p = {0};
    p.pixel.colortype = rgbColor;
    p.pixel.value = ((red & 0xff) << 16)  |
	            ((green & 0xff) << 8) |
	            (blue & 0xff);
    return p.ulong;
}
    { "SystemDetailText",		    HIText,       kThemeTextColorSystemDetail },		    /* 158 */
    { "WhiteText",			    HIText,       kThemeTextColorWhite },			    /* 159 */
    { "TabPaneBackground",		    HIBackground, kThemeBackgroundTabPane },			    /* 160 */
    { "PlacardBackground",		    HIBackground, kThemeBackgroundPlacard },			    /* 161 */
    { "WindowHeaderBackground",		    HIBackground, kThemeBackgroundWindowHeader },		    /* 162 */
    { "ListViewWindowHeaderBackground",	    HIBackground, kThemeBackgroundListViewWindowHeader },	    /* 163 */
    { "SecondaryGroupBoxBackground",	    HIBackground, kThemeBackgroundSecondaryGroupBox },		    /* 164 */
    { "MetalBackground",		    HIBackground, kThemeBackgroundMetal },			    /* 165 */

    /*
     * Colors based on "semantic" NSColors.
     */


/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXClearPixel --
 *
 *	Return the unsigned long value that appears in the pixel
 *	field of the XColor for systemTransparentColor.
 *
 *      This is used in tkMacOSXImage.c.
 *
 * Results:
 *	The unsigned long that appears in the pixel field of the XColor
 *      for systemTransparentPixel.
 *
 * Side effects:
 *	None.
 *----------------------------------------------------------------------
 */
MODULE_SCOPE
unsigned long TkMacOSXClearPixel(
    void)
{
    { "WindowBackgroundColor",		    ttkBackground, 0 },	    					    /* 166 */
    { "WindowBackgroundColor1",		    ttkBackground, 1 },						    /* 167 */
    { "WindowBackgroundColor2",		    ttkBackground, 2 },						    /* 168 */
    { "WindowBackgroundColor3",		    ttkBackground, 3 },						    /* 169 */
    { "WindowBackgroundColor4",		    ttkBackground, 4 },						    /* 170 */
    { "WindowBackgroundColor5",		    ttkBackground, 5 },						    /* 171 */
    { "WindowBackgroundColor6",		    ttkBackground, 6 },						    /* 172 */
    { "WindowBackgroundColor7",		    ttkBackground, 7 },						    /* 173 */
    { "TextColor",			    semantic, 0 },						    /* 174 */
    { "SelectedTextColor",		    semantic, 1 },						    /* 175 */
    { "LabelColor",			    semantic, 2 },						    /* 176 */
    { "ControlTextColor",      		    semantic, 3 },						    /* 177 */
    { "DisabledControlTextColor",	    semantic, 4 },						    /* 178 */
    { "SelectedTabTextColor",		    semantic, 5 },						    /* 179 */
    { "TextBackgroundColor",		    semantic, 6 },						    /* 180 */
    MacPixel p = {0};
    p.pixel.value = 0;
    p.pixel.colortype = clearColor;
    return p.ulong;
}

    { "SelectedTextBackgroundColor",	    semantic, 7 },						    /* 181 */
    { "ControlAccentColor",		    semantic, 8 },						    /* 182 */
    /* Apple's SecondaryLabelColor is the same as their LabelColor so we roll our own. */
    { "SecondaryLabelColor",		    ttkBackground, 14 },					    /* 183 */
    { "LinkColor",			    semantic, 9 },						    /* 184 */
    { NULL,				    0, 0 }
};
#define FIRST_SEMANTIC_COLOR 166
#define MAX_PIXELCODE 184

/*
 *----------------------------------------------------------------------
 *
 * GetEntryFromPixelCode --
 * GetEntryFromPixel --
 *
 *	Extract a SystemColorMapEntry from the table.
 *	Look up a SystemColorDatum which describes the XColor with
 *      the specified value as its pixel field.
 *
 * Results:
 *	Returns false if the code is out of bounds.
 *	A pointer to a SystemColorDatum, or NULL if the pixel value is
 *	invalid.
 *
 * Side effects:
 *	None.
 *	None
 *
 *----------------------------------------------------------------------
 */

static bool
GetEntryFromPixelCode(
    unsigned char code,
SystemColorDatum*
GetEntryFromPixel(
    unsigned long pixel)
    struct SystemColorMapEntry *entry)
{
    MacPixel p = {0};
    int index = rgbColorIndex;
    if (code >= MIN_PIXELCODE && code <= MAX_PIXELCODE) {
	*entry = systemColorMap[code - MIN_PIXELCODE];
	return true;

    p.ulong = pixel;
    if (p.pixel.colortype != rgbColor) {
	index = p.pixel.value;
    }
    if (index < numSystemColors) {
	return systemColorIndex[index];
    } else {
	return false;
	return NULL;
    }
}

    }
}


/*
 *----------------------------------------------------------------------
 *
 * SetCGColorComponents --
 * GetRGBA --
 *
 *	Given a SystemColorDatum and a pointer to an array of 4 CGFloats, store
 *      the associated RGBA color values in the array.  In the case of the
 *	Set the components of a CGColorRef from an XColor pixel value and a
 *      system color map entry.  The pixel value is only used in the case where
 *      RGBColor datum, the unsigned long pixel value containing the RGB values
 *      must also be provided as the pixel parameter.  Otherwise the pixel
 *      the color is of type rgbColor.  In that case the normalized XColor RGB
 *      values are copied into the CGColorRef.
 *      parameter is ignored.
 *
 * Results:
 *	OSStatus
 *	None
 *
 * Side effects:
 *	None.
 *	The array rgba is filled in.
 *
 *----------------------------------------------------------------------
 */

static NSColorSpace* sRGB = NULL;
static CGFloat windowBackground[4] =
    {236.0 / 255, 236.0 / 255, 236.0 / 255, 1.0};

static OSStatus
SetCGColorComponents(
    struct SystemColorMapEntry entry,
static void
GetRGBA(
    SystemColorDatum *entry,
    unsigned long pixel,
    CGColorRef *c)
    CGFloat *rgba)
{
    OSStatus err = noErr;
    NSColor *bgColor, *color = nil;
    CGFloat rgba[4] = {0, 0, 0, 1};

    if (!sRGB) {
	sRGB = [NSColorSpace sRGBColorSpace];
    }

    /*
     * This function is called before our autorelease pool is set up,
     * so it needs its own pool.
     */

    NSAutoreleasePool *pool = [NSAutoreleasePool new];

    switch (entry.type) {
    switch (entry->type) {
    case HIBrush:
	err = ChkErr(HIThemeBrushCreateCGColor, entry.value, c);
	return err;
    case rgbColor:
	rgba[0] = ((pixel >> 16) & 0xff) / 255.0;
	rgba[1] = ((pixel >>  8) & 0xff) / 255.0;
	rgba[2] = ((pixel      ) & 0xff) / 255.0;
	break;
    case ttkBackground:

	/*
	 * Prior to OSX 10.14, getComponents returns black when applied to
	 * windowBackGroundColor.
	 */

	if ([NSApp macOSVersion] < 101400) {
	    for (int i=0; i<3; i++) {
		rgba[i] = windowBackground[i];
	    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;
		rgba[i] += entry->value*8.0 / 255.0;
	    }
	} else {
	    for (int i=0; i<3; i++) {
		rgba[i] -= entry.value*8.0 / 255.0;
		rgba[i] -= entry->value*8.0 / 255.0;
	    }
	}
	break;
    case semantic:
	switch (entry.value) {
	case 0:
    case clearColor:
	    color = [[NSColor textColor] colorUsingColorSpace:sRGB];
	    break;
	case 1:
	rgba[0] = rgba[1] = rgba[2] = 1.0;
	    color = [[NSColor selectedTextColor] colorUsingColorSpace:sRGB];
	    break;
	rgba[3] = 0;
	case 2:
	    if ([NSApp macOSVersion] > 100900) {
#if MAC_OS_X_VERSION_MAX_ALLOWED > 1090
		color = [[NSColor labelColor] colorUsingColorSpace:sRGB];
#endif
	    } else {
		color = [[NSColor textColor] colorUsingColorSpace:sRGB];
	    }
	    break;
	case 3:
	    color = [[NSColor controlTextColor] colorUsingColorSpace:sRGB];
	break;
    case semantic:
	if (entry->index == controlAccentIndex && useFakeAccentColor) {
	    break;
	case 4:
	    color = [[NSColor disabledControlTextColor]
			colorUsingColorSpace:sRGB];
	    break;
	case 5:
	    if ([NSApp macOSVersion] > 100600) {
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
	    color = [[NSColor colorForControlTint: [NSColor currentControlTint]]
			      colorUsingColorSpace:sRGB];
#endif
	} else if (entry->index == selectedTabTextIndex) {
	    int OSVersion = [NSApp macOSVersion];
	    if (OSVersion > 100600 && OSVersion < 110000) {
		color = [[NSColor whiteColor] colorUsingColorSpace:sRGB];
	    } else {
		color = [[NSColor blackColor] colorUsingColorSpace:sRGB];
		color = [[NSColor textColor] colorUsingColorSpace:sRGB];
	    }
	    break;
	case 6:
	    color = [[NSColor textBackgroundColor] colorUsingColorSpace:sRGB];
	    break;
	case 7:
	} else {
	    color = [[NSColor valueForKey:entry->selector] colorUsingColorSpace:sRGB];
	}
	[color getComponents: rgba];
	break;
    default:
	    color = [[NSColor selectedTextBackgroundColor]
			colorUsingColorSpace:sRGB];
	    break;
	break;
	case 8:
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
	    if (@available(macOS 14, *)) {
    }
}
		color = [[NSColor controlAccentColor] colorUsingColorSpace:sRGB];
#else
	    if(false) {
#endif
	    } else {
		color = [[NSColor
			    colorForControlTint:[NSColor currentControlTint]]
			        colorUsingColorSpace: sRGB];
	    }

	    break;
	case 9:
/*
 *----------------------------------------------------------------------
 *
 * 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
	    if ([NSApp macOSVersion] >= 101000) {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
		color = [[NSColor linkColor] colorUsingColorSpace:sRGB];
#endif
	    } else {
 *      the color is of type rgbColor.  In that case the normalized XColor RGB
 *      values are copied into the CGColorRef.  Otherwise the components are
 *      computed from the SystemColorDatum.
 *
 * Results:
 *	True if the function succeeds, false otherwise.
		color = [[NSColor blueColor] colorUsingColorSpace:sRGB];
	    }
	    break;
	default:
 *
 * Side effects:
	    if ([NSApp macOSVersion] >= 101000) {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
		color = [[NSColor labelColor] colorUsingColorSpace:sRGB];
#endif
 *	None.
 *
 *----------------------------------------------------------------------
 */
	    } else {
		color = [[NSColor textColor] colorUsingColorSpace:sRGB];
	    }
	    break;

static Bool
	}
	[color getComponents: rgba];
SetCGColorComponents(
	break;
    case clearColor:
	rgba[3]	= 0.0;
    SystemColorDatum *entry,
    unsigned long pixel,
    CGColorRef *c)
{
    CGFloat rgba[4] = {0, 0, 0, 1};
	break;

    /*
     * There are no HITheme functions which convert Text or background colors
     * This function is called before our autorelease pool is set up,
     * to CGColors.  (GetThemeTextColor has been removed, and it was never
     * possible with backgrounds.)  If we get one of these we return black.
     * so it needs its own pool.
     */

    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    case HIText:
    case HIBackground:

    if (entry->type == HIBrush) {
    default:
	break;
     	OSStatus err = ChkErr(HIThemeBrushCreateCGColor, entry->value, c);
     	return err == noErr;
    }
    GetRGBA(entry, pixel, rgba);
    *c = CGColorCreate(sRGB.CGColorSpace, rgba);
    [pool drain];
    return err;
    return true;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXInDarkMode --
 *
433
434
435
436
437
438
439
440
441
442
443
444

445
446

447
448
449

450
451
452

453
454

455
456

457


458
459
460

461
462
463
464
465
466
467
468
469
470
471




472
473
474

475
476
477
478

479
480
481
482
483
484
485
486
487


488
489
490
491
492

493
494
495

496
497
498

499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514

515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547

548
549
550
551
552
553
554
555


556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616

617
618
619

620
621
622
623
624
625
626
627
628
629

630
631
632

633
634
635

636
637
638
639
640
641



642
643
644
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
401
402
403
404
405
406
407

408
409


410

411
412
413
414

415
416
417

418
419

420

421
422
423
424
425
426


427
428
429
430
431
432
433
434




435
436
437
438
439
440

441

442
443

444

445
446
447
448
449
450


451
452
453
454



455



456



457
















458

































459








460
461





















































462
463
464
465
466
467
468
469
470
471
472

473
474
475
476
477
478
479
480
481
482

483
484
485

486
487
488

489






490
491
492



493
494
495
496
497
498
499
500

501


502

503
504
505
506
507
508
509
510
511
512
513
514
515

516
517
518
519
520
521





522





523
524
525
526

527
528
529

530
531
532
533










534

535



536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553

554
555
556
557
558
559
560
561
562
563
564
565



566
567
568
569
570
571
572
573
574
575
576
577

578

579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597

598

599
600
601


602
603
604


605
606



607




608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639

640
641
642
643
644
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







-


-
-
+
-

+


-
+


-
+

-
+
-

+

+
+

-
-
+







-
-
-
-
+
+
+
+


-
+
-


-
+
-






-
-
+
+


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








+


-
+









-
+


-
+


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








-
+
-
-
+
-
+












-
+





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

-
+


-
+



-
-
-
-
-
-
-
-
-
-

-
+
-
-
-


















-
+
+
+
+
+
+
+





-
-
-
+
+










-
+
-


+
+
+
+

+
+
+
+
+
+
+
+
+
+
+

-
+
-



-
-
+
+

-
-
+
+
-
-
-

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















-
-
-
-



-


-






-
-
+
+








+
-
-
+
+
+
-
+
+


-
+
-
-
-



-
+






-
+




-




-
+







 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE Bool
TkMacOSXInDarkMode(Tk_Window tkwin)
{
    int result = false;

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
    static NSAppearanceName darkAqua = @"NSAppearanceNameDarkAqua";

    if (@available(macOS 10.14, *)) {
    if ([NSApp macOSVersion] >= 101400) {
        TkWindow *winPtr = (TkWindow*) tkwin;
	NSAppearanceName name;
	NSView *view = nil;
	if (winPtr && winPtr->privatePtr) {
	    view = TkMacOSXDrawableView(winPtr->privatePtr);
	    view = TkMacOSXGetNSViewForDrawable((Drawable)winPtr->privatePtr);
	}
	if (view) {
	    result = [view.effectiveAppearance.name isEqualToString:darkAqua];
	    name = [[view effectiveAppearance] name];
	} else {
	    result = [[NSAppearance currentAppearance].name
	    name = [[NSAppearance currentAppearance] name];
			 isEqualToString:darkAqua];
	}
	return (name == NSAppearanceNameDarkAqua);
    }
#else
    (void) tkwin;
#endif

    return result;
    return false;
}

/*
 *----------------------------------------------------------------------
 *
 * TkSetMacColor --
 *
 *	Sets the components of a CGColorRef from an XColor pixel value.
 *      The high order byte of the pixel value is used as an index into
 *      the system color table, and then SetCGColorComponents is called
 *      with the table entry and the pixel value.
 *	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.  The parameter macColor should be a pointer to a CGColorRef.
 *
 * Results:
 *      Returns false if the high order byte is not a valid index, true
 *      Returns false if the color is not found, true otherwise.
 *	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;
    OSStatus err = -1;
    struct SystemColorMapEntry entry;

    SystemColorDatum *entry = GetEntryFromPixel(pixel);
    if (GetEntryFromPixelCode((pixel >> 24) & 0xff, &entry)) {
	err = ChkErr(SetCGColorComponents, entry, pixel, color);
    }

    return (err == noErr);
}

    if (entry) {
/*
 *----------------------------------------------------------------------
 *
 * TkpInitGCCache, TkpFreeGCCache, CopyCachedColor, SetCachedColor --
 *
 *	Maintain a per-GC cache of previously converted CGColorRefs
 *
 * Results:
 *	None resp. retained CGColorRef for CopyCachedColor()
 *
 * Side effects:M
 *	None.
 *
 *----------------------------------------------------------------------
 */

	return SetCGColorComponents(entry, pixel, color);
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) {
    } else {
	    cgColor = gcCache->cachedBackgroundColor;
	}
	if (cgColor) {
	    CFRetain(cgColor);
	}
    }
    return cgColor;
}
	return false;
    }

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:
 *	Returns nil if not a real pixel, NSColor* otherwise.
 *	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;
    NSColor *nsColor = nil;

    if (cgColor) {
    TkSetMacColor(pixel, &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:CGColorGetNumberOfComponents(cgColor)];
	[colorSpace release];
	CFRelease(cgColor);
    }
    return nsColor;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXSetColorInContext --
 *
 *	Sets fill and stroke color in the given CG context from an X
 *	Sets the fill and stroke colors in the given CGContext to the CGColor
 *	pixel value, or if the pixel code indicates a system color,
 *	sets the corresponding brush, textColor or background via
 *	which corresponds to the XColor having the specified value for its pixel
 *	HITheme APIs if available or Appearance mgr APIs.
 *	field.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXSetColorInContext(
    GC gc,
    TCL_UNUSED(GC),
    unsigned long pixel,
    CGContextRef context)
{
    OSStatus err = noErr;
    CGColorRef cgColor = nil;
    struct SystemColorMapEntry entry;
    CGRect rect;
    int code = (pixel >> 24) & 0xff;
    HIThemeBackgroundDrawInfo info = {0, kThemeStateActive, 0};;

    SystemColorDatum *entry = GetEntryFromPixel(pixel);
    if (code < FIRST_SEMANTIC_COLOR) {
	cgColor = CopyCachedColor(gc, pixel);
    }
    if (!cgColor && GetEntryFromPixelCode(code, &entry)) {
	switch (entry.type) {

    if (entry) {
	switch (entry->type) {
	case HIBrush:
	    err = ChkErr(HIThemeSetFill, entry.value, NULL, context,
	    err = ChkErr(HIThemeSetFill, entry->value, NULL, context,
		    kHIThemeOrientationNormal);
	    if (err == noErr) {
		err = ChkErr(HIThemeSetStroke, entry.value, NULL, context,
		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:
	    err = ChkErr(SetCGColorComponents, entry, pixel, &cgColor);
	    SetCGColorComponents(entry, pixel, &cgColor);
	    if (err == noErr) {
		SetCachedColor(gc, pixel, cgColor);
	    }
	    break;
	}
    }
    if (cgColor) {
	CGContextSetFillColorWithColor(context, cgColor);
	CGContextSetStrokeColorWithColor(context, cgColor);
	CGColorRelease(cgColor);
    }
    if (err != noErr) {
	TkMacOSXDbgMsg("Ignored unknown pixel value 0x%lx", pixel);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetColor --
 *
 *	Allocate a new TkColor for the color with the given name.
 *	Create a new TkColor for the color with the given name, for use in the
 *      specified window. The colormap field is set to lightColormap if the
 *      window has a LightAqua appearance, or darkColormap if the window has a
 *      DarkAqua appearance.  TkColors with different colormaps are managed
 *      separately in the per-display table of TkColors maintained by Tk.
 *
 *      This function is called by Tk_GetColor.
 *
 * Results:
 *	Returns a newly allocated TkColor, or NULL on failure.
 *
 * Side effects:
 *	May invalidate the colormap cache associated with tkwin upon
 *	allocating a new colormap entry. Allocates a new TkColor
 *	structure.
 *
 *	Allocates memory for the TkColor structure.
 *
 *----------------------------------------------------------------------
 */

TkColor *
TkpGetColor(
    Tk_Window tkwin,		/* Window in which color will be used. */
    Tk_Uid name)		/* Name of color to be allocated (in form
				 * suitable for passing to XParseColor). */
{
    Display *display = tkwin != None ? Tk_Display(tkwin) : NULL;
    Display *display = NULL;
    Colormap colormap = tkwin!= None ? Tk_Colormap(tkwin) : None;
    TkColor *tkColPtr;
    XColor color;
    Colormap colormap = tkwin ? Tk_Colormap(tkwin) : noColormap;
    NSView *view = nil;
    static Bool initialized = NO;
    static NSColorSpace* sRGB = nil;

    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. Otherwise, XParseColor
     * Check to see if this is a system color. If not, just call XParseColor.
     * will do all the work.
     */

    if (strncasecmp(name, "system", 6) == 0) {
	Tcl_Obj *strPtr = Tcl_NewStringObj(name+6, -1);
	int idx, result;
	Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&systemColors, name + 6);
	MacPixel p = {0};

	result = Tcl_GetIndexFromObjStruct(NULL, strPtr, systemColorMap,
		sizeof(struct SystemColorMapEntry), NULL, TCL_EXACT, &idx);
	if (hPtr != NULL) {
	    SystemColorDatum *entry = (SystemColorDatum *)Tcl_GetHashValue(hPtr);
	Tcl_DecrRefCount(strPtr);
	if (result == TCL_OK) {
	    OSStatus err;
	    CGColorRef c;
	    unsigned char pixelCode = idx + MIN_PIXELCODE;
	    struct SystemColorMapEntry entry = systemColorMap[idx];

	    err = ChkErr(SetCGColorComponents, entry, 0, &c);

	    p.pixel.colortype = entry->type;
	    p.pixel.value = entry->index;
	    color.pixel = p.ulong;
	    if (entry->type == semantic) {
		CGFloat rgba[4];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
		if (@available(macOS 10.14, *)) {
		    NSAppearance *savedAppearance = [NSAppearance currentAppearance];
		    NSAppearance *windowAppearance = savedAppearance;
		    if (view) {
			windowAppearance = [view effectiveAppearance];
		    }
		    if ([windowAppearance name] == NSAppearanceNameDarkAqua) {
			colormap = darkColormap;
		    } else {
			colormap = lightColormap;
		    }
		    [NSAppearance setCurrentAppearance:windowAppearance];
		    GetRGBA(entry, p.ulong, rgba);
		    [NSAppearance setCurrentAppearance:savedAppearance];
		} else {
		    GetRGBA(entry, p.ulong, rgba);
		}
#else
		GetRGBA(entry, p.ulong, rgba);
#endif
		color.red   = rgba[0] * 65535.0;
		color.green = rgba[1] * 65535.0;
		color.blue  = rgba[2] * 65535.0;
		goto validXColor;
	    } else if (SetCGColorComponents(entry, 0, &c)) {
	    if (err == noErr) {
		const size_t n = CGColorGetNumberOfComponents(c);
		const CGFloat *rgba = CGColorGetComponents(c);

		switch (n) {
		case 4:
		    color.red   = rgba[0] * 65535.0;
		    color.green = rgba[1] * 65535.0;
		    color.blue  = rgba[2] * 65535.0;
		    break;
		case 2:
		    color.red = color.green = color.blue = rgba[0] * 65535.0;
		    break;
		default:
		    Tcl_Panic("CGColor with %d components", (int) n);
		}
		color.pixel = ((((((pixelCode << 8)
			| ((color.red   >> 8) & 0xff)) << 8)
			| ((color.green >> 8) & 0xff)) << 8)
			| ((color.blue  >> 8) & 0xff));
		CGColorRelease(c);
		goto validXColor;
	    }
	    CGColorRelease(c);
	}
    }

    if (TkParseColor(display, colormap, name, &color) == 0) {
	return NULL;
    }

validXColor:
    tkColPtr = (TkColor *)ckalloc(sizeof(TkColor));
    tkColPtr->color = color;

    tkColPtr->colormap = colormap;
    tkColPtr->color = color;
    return tkColPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetColorByValue --
 *
 *	Given an pointer to an XColor, construct a TkColor whose red, green and
 *	Given a desired set of red-green-blue intensities for a color,
 *	locate a pixel value to use to draw that color in a given
 *	blue intensities match those of the XColor as closely as possible.  For
 *	the Macintosh, this means that the colortype bitfield of the pixel
 *	value will be RGBColor and that the color intensities stored in its
 *	window.
 *	24-bit value bitfield are computed from the 16-bit red green and blue
 *	values in the XColor by dividing by 256.
 *
 * Results:
 *	The return value is a pointer to an TkColor structure that
 *	A pointer to a newly allocated TkColor structure.
 *	indicates the closest red, blue, and green intensities available
 *	to those specified in colorPtr, and also specifies a pixel
 *	value to use to draw in that color.
 *
 * Side effects:
 *	May invalidate the colormap cache for the specified window.
 *	Allocates a new TkColor structure.
 *	Allocates memory for a TkColor structure.
 *
 *----------------------------------------------------------------------
 */

TkColor *
TkpGetColorByValue(
    Tk_Window tkwin,		/* Window in which color will be used. */
    TCL_UNUSED(Tk_Window),		/* Window in which color will be used. */
    XColor *colorPtr)		/* Red, green, and blue fields indicate
				 * desired color. */
{
    TkColor *tkColPtr = (TkColor *)ckalloc(sizeof(TkColor));
    (void)tkwin;

    tkColPtr->color.red = colorPtr->red;
    tkColPtr->color.green = colorPtr->green;
    tkColPtr->color.blue = colorPtr->blue;
    tkColPtr->color.pixel = TkpGetPixel(&tkColPtr->color);
    tkColPtr->color.pixel = TkpGetPixel(colorPtr);
    return tkColPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Stub functions --
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
721
722
723
724
725
726
727

728
729
730


731
732
733
734
735
736
737




738
739
740
741
742

743




744
745

746
747
748
749
750
751
752
753


754
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







-
+


-
-







-
-
-
-
+
+
+
+

-
+
-
-
-
-


-
+
+






-
-
+
+

-
-
-





-
-
-
-
-
+
+
+
+
+

-
-
-
-
-
-

-
-
-
+
+












 *
 *----------------------------------------------------------------------
 */

Status
XAllocColor(
    Display *display,		/* Display. */
    Colormap map,		/* Not used. */
    TCL_UNUSED(Colormap),		/* Not used. */
    XColor *colorPtr)		/* XColor struct to modify. */
{
    (void)map;

    display->request++;
    colorPtr->pixel = TkpGetPixel(colorPtr);
    return 1;
}

Colormap
XCreateColormap(
    Display *display,		/* Display. */
    Window window,		/* X window. */
    Visual *visual,		/* Not used. */
    int alloc)			/* Not used. */
    TCL_UNUSED(Display *),		/* Display. */
    TCL_UNUSED(Window),		/* X window. */
    TCL_UNUSED(Visual *),		/* Not used. */
    TCL_UNUSED(int))			/* Not used. */
{
    static Colormap index = 1;
    static Colormap index = 16;
    (void)display;
    (void)window;
    (void)visual;
    (void)alloc;

    /*
     * Just return a new value each time.
     * Just return a new value each time, large enough that it will not
     * conflict with any value of the macColormap enum.
     */
    return index++;
}

int
XFreeColormap(
    Display* display,		/* Display. */
    Colormap colormap)		/* Colormap. */
    TCL_UNUSED(Display *),		/* Display. */
    TCL_UNUSED(Colormap))		/* Colormap. */
{
    (void)display;
    (void)colormap;

    return Success;
}

int
XFreeColors(
    Display* display,		/* Display. */
    Colormap colormap,		/* Colormap. */
    unsigned long* pixels,	/* Array of pixels. */
    int npixels,		/* Number of pixels. */
    unsigned long planes)	/* Number of pixel planes. */
    TCL_UNUSED(Display *),		/* Display. */
    TCL_UNUSED(Colormap),		/* Colormap. */
    TCL_UNUSED(unsigned long *),	/* Array of pixels. */
    TCL_UNUSED(int),		/* Number of pixels. */
    TCL_UNUSED(unsigned long))	/* Number of pixel planes. */
{
    (void)display;
    (void)colormap;
    (void)pixels;
    (void)npixels;
    (void)planes;

    /*
     * The Macintosh version of Tk uses TrueColor. Nothing
     * needs to be done to release colors as there really is
     * no colormap in the Tk sense.
     * Nothing needs to be done to release colors as there really is no
     * colormap in the Tk sense.
     */
    return Success;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Added macosx/tkMacOSXColor.h.








































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef MACOSXCOLOR_H
#define MACOSXCOLOR_H
/*
 * The generic Tk code uses the X11 GC type to describe a graphics context.
 * (A GC is a pointer to a struct XGCValues).  The foreground and background
 * colors in a GC are unsigned longs.  These are meant to be used as indexes
 * into a table of XColors, where an XColor is declared in Xlib.h as:
 * typedef struct {
 *       unsigned long pixel;
 *       unsigned short red, green, blue;
 *       char flags;
 *       char pad;
 * } XColor;
 *
 * The xlib function XParseColor creates XColors from strings.  It recognizes
 * literal hexadecimal color specifications such as "#RRGGBB" as well as the
 * standard X11 color names.  When XParseColor creates an XColor it fills in
 * all of the fields except for the pixel field, and then passes the XColor
 * to TkpGetPixel to get a value to use for the pixel field. Since TkpGetPixel
 * is platform specific, each platform is free to choose a value which can
 * be used to set the foreground or background color in the platform's graphics
 * context.
 *
 * Tk represents a color by a struct TkColor, which extends the XColor struct.
 * Tk provides a mapping from color names to TkColors which extends the mapping
 * provided by XParseColor but also allows for platform specific color names.
 * By convention, these platform specific color names begin with the string
 * "system".  The mapping from names to TkColors is implemented by the function
 * TkpGetColor defined for the Macintosh in this file.  The pixel field in the
 * XColor contained in a TkColor will be stored in the X11 graphics context.
 * In X11 the pixel field is used as an index into a colormap.  On the Mac
 * the high order byte of the pixel is used to indicate a color type and
 * the low 24 bits are either used as an rgb value (if the type is rgbColor)
 * or as an index into a table of color descriptions.
 */

enum colorType {
    rgbColor,      /* The 24 bit value is an rgb color. */
    clearColor,    /* The unique rgba color with all channels 0. */
    HIBrush,       /* A HITheme brush color.*/
    ttkBackground, /* A background color which indicates nesting level.*/
    semantic,      /* A semantic NSColor.*/
};

typedef struct xpixel_t {
    unsigned value: 24;     /* Either RGB or an index into systemColorData. */
    unsigned colortype: 8;
} xpixel;

typedef union MacPixel_t {
    unsigned long ulong;
    xpixel pixel;
} MacPixel;

/*
 * We maintain two colormaps, one for the LightAqua appearance and one for the
 * DarkAqua appearance.
 */

enum macColormap {
    noColormap,
    lightColormap,
    darkColormap,
};

/*
 * In TkMacOSXColor.c a Tk hash table is constructed from the static data
 * below to map system color names to CGColors.
 */

typedef struct {
    const char *name;
    enum colorType type;
    int value;
    const char *macName;
    /* Fields below are filled in after or during construction of the hash table. */
    int index;
    NSString *selector;
} SystemColorDatum;

/*
 * WARNING: Semantic colors which are not supported on all systems must be
 * preceded by a backup color with the same name which *is* supported.  Systems
 * which do support the color will replace the backup value when the table is
 * constructed.  Failing to ensure this will result in a Tcl_Panic abort.
 */

static SystemColorDatum systemColorData[] = {
{"Pixel",				rgbColor, 0, NULL, 0, NULL },
{"Transparent",			       	clearColor,   0, NULL, 0, NULL },

{"Highlight",				HIBrush,  kThemeBrushPrimaryHighlightColor, NULL, 0, NULL },
{"HighlightSecondary",		    	HIBrush,  kThemeBrushSecondaryHighlightColor, NULL, 0, NULL },
{"HighlightText",			HIBrush,  kThemeBrushBlack, NULL, 0, NULL },
{"HighlightAlternate",			HIBrush,  kThemeBrushAlternatePrimaryHighlightColor, NULL, 0, NULL },
{"PrimaryHighlightColor",		HIBrush,  kThemeBrushPrimaryHighlightColor, NULL, 0, NULL },
{"ButtonFace",				HIBrush,  kThemeBrushButtonFaceActive, NULL, 0, NULL },
{"SecondaryHighlightColor",		HIBrush,  kThemeBrushSecondaryHighlightColor, NULL, 0, NULL },
{"ButtonFrame",				HIBrush,  kThemeBrushButtonFrameActive, NULL, 0, NULL },
{"AlternatePrimaryHighlightColor",      HIBrush,  kThemeBrushAlternatePrimaryHighlightColor, NULL, 0, NULL },
{"WindowBody",				HIBrush,  kThemeBrushDocumentWindowBackground, NULL, 0, NULL },
{"SheetBackground",			HIBrush,  kThemeBrushSheetBackground, NULL, 0, NULL },
{"MenuActive",				HIBrush,  kThemeBrushMenuBackgroundSelected, NULL, 0, NULL },
{"Menu",				HIBrush,  kThemeBrushMenuBackground, NULL, 0, NULL },
{"DialogBackgroundInactive",		HIBrush,  kThemeBrushDialogBackgroundInactive, NULL, 0, NULL },
{"DialogBackgroundActive",		HIBrush,  kThemeBrushDialogBackgroundActive, NULL, 0, NULL },
{"AlertBackgroundActive",		HIBrush,  kThemeBrushAlertBackgroundActive, NULL, 0, NULL },
{"AlertBackgroundInactive",		HIBrush,  kThemeBrushAlertBackgroundInactive, NULL, 0, NULL },
{"ModelessDialogBackgroundActive",	HIBrush,  kThemeBrushModelessDialogBackgroundActive, NULL, 0, NULL },
{"ModelessDialogBackgroundInactive",	HIBrush,  kThemeBrushModelessDialogBackgroundInactive, NULL, 0, NULL },
{"UtilityWindowBackgroundActive",	HIBrush,  kThemeBrushUtilityWindowBackgroundActive, NULL, 0, NULL },
{"UtilityWindowBackgroundInactive",	HIBrush,  kThemeBrushUtilityWindowBackgroundInactive, NULL, 0, NULL },
{"ListViewSortColumnBackground",	HIBrush,  kThemeBrushListViewSortColumnBackground, NULL, 0, NULL },
{"ListViewBackground",			HIBrush,  kThemeBrushListViewBackground, NULL, 0, NULL },
{"IconLabelBackground",			HIBrush,  kThemeBrushIconLabelBackground, NULL, 0, NULL },
{"ListViewSeparator",			HIBrush,  kThemeBrushListViewSeparator, NULL, 0, NULL },
{"ChasingArrows",			HIBrush,  kThemeBrushChasingArrows, NULL, 0, NULL },
{"DragHilite",				HIBrush,  kThemeBrushDragHilite, NULL, 0, NULL },
{"DocumentWindowBackground",		HIBrush,  kThemeBrushDocumentWindowBackground, NULL, 0, NULL },
{"FinderWindowBackground",		HIBrush,  kThemeBrushFinderWindowBackground, NULL, 0, NULL },
{"ScrollBarDelimiterActive",		HIBrush,  kThemeBrushScrollBarDelimiterActive, NULL, 0, NULL },
{"ScrollBarDelimiterInactive",		HIBrush,  kThemeBrushScrollBarDelimiterInactive, NULL, 0, NULL },
{"FocusHighlight",			HIBrush,  kThemeBrushFocusHighlight, NULL, 0, NULL },
{"PopupArrowActive",			HIBrush,  kThemeBrushPopupArrowActive, NULL, 0, NULL },
{"PopupArrowPressed",			HIBrush,  kThemeBrushPopupArrowPressed, NULL, 0, NULL },
{"PopupArrowInactive",			HIBrush,  kThemeBrushPopupArrowInactive, NULL, 0, NULL },
{"AppleGuideCoachmark",			HIBrush,  kThemeBrushAppleGuideCoachmark, NULL, 0, NULL },
{"IconLabelBackgroundSelected",		HIBrush,  kThemeBrushIconLabelBackgroundSelected, NULL, 0, NULL },
{"StaticAreaFill",			HIBrush,  kThemeBrushStaticAreaFill, NULL, 0, NULL },
{"ActiveAreaFill",			HIBrush,  kThemeBrushActiveAreaFill, NULL, 0, NULL },
{"ButtonFrameActive",			HIBrush,  kThemeBrushButtonFrameActive, NULL, 0, NULL },
{"ButtonFrameInactive",			HIBrush,  kThemeBrushButtonFrameInactive, NULL, 0, NULL },
{"ButtonFaceActive",			HIBrush,  kThemeBrushButtonFaceActive, NULL, 0, NULL },
{"ButtonFaceInactive",			HIBrush,  kThemeBrushButtonFaceInactive, NULL, 0, NULL },
{"ButtonFacePressed",			HIBrush,  kThemeBrushButtonFacePressed, NULL, 0, NULL },
{"ButtonActiveDarkShadow",		HIBrush,  kThemeBrushButtonActiveDarkShadow, NULL, 0, NULL },
{"ButtonActiveDarkHighlight",		HIBrush,  kThemeBrushButtonActiveDarkHighlight, NULL, 0, NULL },
{"ButtonActiveLightShadow",		HIBrush,  kThemeBrushButtonActiveLightShadow, NULL, 0, NULL },
{"ButtonActiveLightHighlight",		HIBrush,  kThemeBrushButtonActiveLightHighlight, NULL, 0, NULL },
{"ButtonInactiveDarkShadow",		HIBrush,  kThemeBrushButtonInactiveDarkShadow, NULL, 0, NULL },
{"ButtonInactiveDarkHighlight",		HIBrush,  kThemeBrushButtonInactiveDarkHighlight, NULL, 0, NULL },
{"ButtonInactiveLightShadow",		HIBrush,  kThemeBrushButtonInactiveLightShadow, NULL, 0, NULL },
{"ButtonInactiveLightHighlight",	HIBrush,  kThemeBrushButtonInactiveLightHighlight, NULL, 0, NULL },
{"ButtonPressedDarkShadow",		HIBrush,  kThemeBrushButtonPressedDarkShadow, NULL, 0, NULL },
{"ButtonPressedDarkHighlight",		HIBrush,  kThemeBrushButtonPressedDarkHighlight, NULL, 0, NULL },
{"ButtonPressedLightShadow",		HIBrush,  kThemeBrushButtonPressedLightShadow, NULL, 0, NULL },
{"ButtonPressedLightHighlight",		HIBrush,  kThemeBrushButtonPressedLightHighlight, NULL, 0, NULL },
{"BevelActiveLight",			HIBrush,  kThemeBrushBevelActiveLight, NULL, 0, NULL },
{"BevelActiveDark",			HIBrush,  kThemeBrushBevelActiveDark, NULL, 0, NULL },
{"BevelInactiveLight",			HIBrush,  kThemeBrushBevelInactiveLight, NULL, 0, NULL },
{"BevelInactiveDark",			HIBrush,  kThemeBrushBevelInactiveDark, NULL, 0, NULL },
{"NotificationWindowBackground",	HIBrush,  kThemeBrushNotificationWindowBackground, NULL, 0, NULL },
{"MovableModalBackground",		HIBrush,  kThemeBrushMovableModalBackground, NULL, 0, NULL },
{"SheetBackgroundOpaque",		HIBrush,  kThemeBrushSheetBackgroundOpaque, NULL, 0, NULL },
{"DrawerBackground",			HIBrush,  kThemeBrushDrawerBackground, NULL, 0, NULL },
{"ToolbarBackground",			HIBrush,  kThemeBrushToolbarBackground, NULL, 0, NULL },
{"SheetBackgroundTransparent",		HIBrush,  kThemeBrushSheetBackgroundTransparent, NULL, 0, NULL },
{"MenuBackground",			HIBrush,  kThemeBrushMenuBackground, NULL, 0, NULL },
{"MenuBackgroundSelected",		HIBrush,  kThemeBrushMenuBackgroundSelected, NULL, 0, NULL },
{"ListViewOddRowBackground",		HIBrush,  kThemeBrushListViewOddRowBackground, NULL, 0, NULL },
{"ListViewEvenRowBackground",		HIBrush,  kThemeBrushListViewEvenRowBackground, NULL, 0, NULL },
{"ListViewColumnDivider",		HIBrush,  kThemeBrushListViewColumnDivider, NULL, 0, NULL },

    /*
     * Dynamic Colors
     */

{"WindowBackgroundColor",	    ttkBackground, 0, NULL, 0, NULL },
{"WindowBackgroundColor1",	    ttkBackground, 1, NULL, 0, NULL },
{"WindowBackgroundColor2",	    ttkBackground, 2, NULL, 0, NULL },
{"WindowBackgroundColor3",	    ttkBackground, 3, NULL, 0, NULL },
{"WindowBackgroundColor4",	    ttkBackground, 4, NULL, 0, NULL },
{"WindowBackgroundColor5",	    ttkBackground, 5, NULL, 0, NULL },
{"WindowBackgroundColor6",	    ttkBackground, 6, NULL, 0, NULL },
{"WindowBackgroundColor7",	    ttkBackground, 7, NULL, 0, NULL },
/* Apple's SecondaryLabelColor is the same as their LabelColor so we roll our own. */
{"SecondaryLabelColor",		    ttkBackground, 14, NULL, 0, NULL },
/* Color to use for notebook tab labels -- depends on OS version. */
{"SelectedTabTextColor",	    semantic, 0, "textColor", 0, NULL },
/* Semantic colors that we simulate on older systems which don't supoort them. */
{"SelectedMenuItemTextColor",       semantic, 0, "selectedMenuItemTextColor", 0, NULL },
{"ControlAccentColor",		    semantic, 0, "controlAccentColor", 0, NULL },
{"LabelColor",                      semantic, 0, "blackColor", 0, NULL },
{"LinkColor",			    semantic, 0, "blueColor", 0, NULL },
{"PlaceholderTextColor",	    semantic, 0, "grayColor", 0, NULL },
{"SeparatorColor",		    semantic, 0, "grayColor", 0, NULL },
{"UnemphasizedSelectedTextBackgroundColor", semantic, 0, "grayColor", 0, NULL },
{NULL,				    0, 0, NULL, 0, NULL }
};

#endif
/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXConfig.c.

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






-
-
+
+







/*
 * 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"

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
98
99
100
101
102
103
104
105
106
107
108



109






110
111

98
99
100
101
102
103
104


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







-
-


+
+
+

+
+
+
+
+
+


+
#define NSFullScreenWindowMask NSWindowStyleMaskFullScreen
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
#define NSStringPboardType NSPasteboardTypeString
#define NSOnState NSControlStateValueOn
#define NSOffState NSControlStateValueOff
// Now we are also changing names of methods!
#define graphicsContextWithGraphicsPort graphicsContextWithCGContext
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 110000
#define NSWindowStyleMaskTexturedBackground 0
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000
#define GET_NSCONTEXT(context, flip) [NSGraphicsContext		\
	    graphicsContextWithGraphicsPort:context flipped:flip]
#else
#define GET_NSCONTEXT(context, flip) [NSGraphicsContext		\
	    graphicsContextWithCGContext:context flipped:NO]
#endif

#endif

Changes to macosx/tkMacOSXCursor.c.

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 <[email protected]>
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2006-2009 Daniel A. Steffen <[email protected]>
 *
 * 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
197
198
199
200
201
202
203
204
205
183
184
185
186
187
188
189









190
191
192
193
194
195
196







-
-
-
-
-
-
-
-
-








/*
 * 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);

267
268
269
270
271
272
273
274

275
276
277
278
279
280
281
258
259
260
261
262
263
264

265
266
267
268
269
270
271
272







-
+







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

371
372
373
374
375
376
377
378

379
380
381
382
383
384
385
386
387
388
389
390
391
392
362
363
364
365
366
367
368

369
370
371
372
373
374
375

376
377
378
379
380
381
382







-
+






-







 *
 *----------------------------------------------------------------------
 */

TkCursor *
TkGetCursorByName(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    Tk_Window tkwin,		/* Window in which cursor will be used. */
    TCL_UNUSED(Tk_Window),		/* Window in which cursor will be used. */
    Tk_Uid string)		/* Description of cursor. See manual entry
				 * for details on legal syntax. */
{
    TkMacOSXCursor *macCursorPtr = NULL;
    const char **argv = NULL;
    int argc;
    (void)tkwin;

    /*
     * All cursor names are valid lists of one element (for
     * TkX11-compatibility), even unadorned system cursor names.
     */

    if (Tcl_SplitList(interp, string, &argc, &argv) == TCL_OK) {
426
427
428
429
430
431
432
433
434
435
436
437
438
439









440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
416
417
418
419
420
421
422







423
424
425
426
427
428
429
430
431
432










433
434
435
436
437
438
439







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

-
-
-
-
-
-
-
-
-
-







 *	Allocates a new cursor.
 *
 *----------------------------------------------------------------------
 */

TkCursor *
TkCreateCursorFromData(
    Tk_Window tkwin,		/* Window in which cursor will be used. */
    const char *source,		/* Bitmap data for cursor shape. */
    const char *mask,		/* Bitmap data for cursor mask. */
    int width, int height,	/* Dimensions of cursor. */
    int xHot, int yHot,		/* Location of hot-spot in cursor. */
    XColor fgColor,		/* Foreground color for cursor. */
    XColor bgColor)		/* Background color for cursor. */
    TCL_UNUSED(Tk_Window),		/* Window in which cursor will be used. */
    TCL_UNUSED(const char *),		/* Bitmap data for cursor shape. */
    TCL_UNUSED(const char *),		/* Bitmap data for cursor mask. */
    TCL_UNUSED(int),	/* Dimensions of cursor. */
    TCL_UNUSED(int),
    TCL_UNUSED(int),		/* Location of hot-spot in cursor. */
    TCL_UNUSED(int),
    TCL_UNUSED(XColor),		/* Foreground color for cursor. */
    TCL_UNUSED(XColor))		/* Background color for cursor. */
{
    (void)tkwin;
    (void)source;
    (void)mask;
    (void)width;
    (void)height;
    (void)xHot;
    (void)yHot;
    (void)fgColor;
    (void)bgColor;

    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpFreeCursor --
471
472
473
474
475
476
477
478

479
480
481
482
483
484
485
453
454
455
456
457
458
459

460
461
462
463
464
465
466
467







-
+







void
TkpFreeCursor(
    TkCursor *cursorPtr)
{
    TkMacOSXCursor *macCursorPtr = (TkMacOSXCursor *) cursorPtr;

    [macCursorPtr->macCursor release];
    macCursorPtr->macCursor = NULL;
    macCursorPtr->macCursor = nil;
    if (macCursorPtr == gCurrentCursor) {
	gCurrentCursor = NULL;
    }
}

/*
 *----------------------------------------------------------------------
494
495
496
497
498
499
500
501

502
503

504
505
506
507
508
509
510
511

512
513
514
515
516
517
518
476
477
478
479
480
481
482

483
484

485
486
487
488
489
490



491
492
493
494
495
496
497
498







-
+

-
+





-
-
-
+







 *
 * Side effects:
 *	Changes the Macintosh mouse cursor.
 *
 *----------------------------------------------------------------------
 */

void
static void
TkMacOSXInstallCursor(
    int resizeOverride)
    void)
{
    TkMacOSXCursor *macCursorPtr = gCurrentCursor;
    static int cursorHidden = 0;
    int cursorNone = 0;

    gResizeOverride = resizeOverride;

    if (resizeOverride || !macCursorPtr) {
    if (!macCursorPtr) {
	[[NSCursor arrowCursor] set];
    } else {
	switch (macCursorPtr->type) {
	case NONE:
	    if (!cursorHidden) {
		cursorHidden = 1;
		[NSCursor hide];
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581

582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
532
533
534
535
536
537
538




539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556

557
558























559
560
561
562
563
564
565
566
567
568







-
-
-
-


















-
+

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











void
TkpSetCursor(
    TkpCursor cursor)
{
    int cursorChanged = 1;

    if (!gTkOwnsCursor) {
	return;
    }

    if (cursor == None) {
	/*
	 * This is a little tricky. We can't really tell whether
	 * gCurrentCursor is NULL because it was NULL last time around or
	 * because we just freed the current cursor. So if the input cursor is
	 * NULL, we always need to reset it, we can't trust the cursorChanged
	 * logic.
	 */

	gCurrentCursor = NULL;
    } else {
	if (gCurrentCursor == (TkMacOSXCursor *) cursor) {
	    cursorChanged = 0;
	}
	gCurrentCursor = (TkMacOSXCursor *) cursor;
    }

    if (Tk_MacOSXIsAppInFront() && cursorChanged) {
	TkMacOSXInstallCursor(gResizeOverride);
	TkMacOSXInstallCursor();
    }
}

/*
 *----------------------------------------------------------------------
 *
 * 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 <[email protected]>
 * Copyright © 1995-1996 Sun Microsystems, Inc.
 * Copyright © 2008-2009 Apple Inc.
 * Copyright © 2008-2009 Daniel A. Steffen <[email protected]>
 *
 * 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 <[email protected]>
 * Copyright © 2001-2009, Apple Inc.
 * Copyright © 2006-2009 Daniel A. Steffen <[email protected]>
 *
 * 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 <[email protected]>
 * Copyright © 2001-2009, Apple Inc.
 * Copyright © 2005-2009 Daniel A. Steffen <[email protected]>
 *
 * 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.

38
39
40
41
42
43
44
45

46
47
48


49
50
51
52
53
54
55
38
39
40
41
42
43
44

45
46
47

48
49
50
51
52
53
54
55
56







-
+


-
+
+







#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		"#a3a3a3"
#define DISABLED		"systemDisabledControlTextColor"
#define IGNORED                 "#abcdef"

/*
 * Defaults for labels, buttons, checkbuttons, and radiobuttons:
 */

#define DEF_BUTTON_ANCHOR		"center"
#define DEF_BUTTON_ACTIVE_BG_COLOR	ACTIVE_BG
84
85
86
87
88
89
90
91
92
93
94
95
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
100
101







-
-
-
-

-

-
-
-
-

-







#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
189
190
191
192
193
194
195
196

197
198
199
200
201
202
203
180
181
182
183
184
185
186

187
188
189
190
191
192
193
194







-
+







#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		"#b3b3b3"
#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"
307
308
309
310
311
312
313
314
315


316
317
318


319
320
321


322
323
324

325
326
327

328
329
330
331


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






349
350
351
352
353
354
355
356
357
358
359
360

361
362
363
364
365
366
367
298
299
300
301
302
303
304


305
306
307


308
309
310


311
312
313
314

315
316
317

318
319
320


321
322
323
324
325
326
327
328
329
330
331
332
333






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

351
352
353
354
355
356
357
358







-
-
+
+

-
-
+
+

-
-
+
+


-
+


-
+


-
-
+
+











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











-
+







#define DEF_MENU_ENTRY_SELECT		NULL
#define DEF_MENU_ENTRY_UNDERLINE	"-1"

/*
 * Defaults for menus overall:
 */

#define DEF_MENU_ACTIVE_BG_COLOR	"systemMenuActive"
#define DEF_MENU_ACTIVE_BG_MONO		BLACK
#define DEF_MENU_ACTIVE_BG_COLOR	IGNORED
#define DEF_MENU_ACTIVE_BG_MONO		IGNORED
#define DEF_MENU_ACTIVE_BORDER_WIDTH	"0"
#define DEF_MENU_ACTIVE_FG_COLOR	"systemMenuActiveText"
#define DEF_MENU_ACTIVE_FG_MONO		WHITE
#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		"systemMenu"
#define DEF_MENU_BG_MONO		WHITE
#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	"systemMenuDisabled"
#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			"systemMenuText"
#define DEF_MENU_FG			"#010000"  /* Detects custom fg. */
#define DEF_MENU_POST_COMMAND		""
#define DEF_MENU_RELIEF			"flat"
#define DEF_MENU_SELECT_COLOR		"systemMenuActive"
#define DEF_MENU_SELECT_MONO		BLACK
#define DEF_MENU_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	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_ACTIVE_BG_COLOR	NORMAL_BG /*ignored*/
#define DEF_MENUBUTTON_ACTIVE_BG_MONO	NORMAL_BG /*ignored*/
#define DEF_MENUBUTTON_ACTIVE_FG_COLOR	"systemTextColor"
#define DEF_MENUBUTTON_ACTIVE_FG_MONO	"systemTextColor"
#define DEF_MENUBUTTON_BG_COLOR		NORMAL_BG /*ignored*/
#define DEF_MENUBUTTON_BG_MONO		NORMAL_BG /*ignored*/
#define DEF_MENUBUTTON_BITMAP		""
#define DEF_MENUBUTTON_BORDER_WIDTH	"0"
#define DEF_MENUBUTTON_CURSOR		""
#define DEF_MENUBUTTON_DIRECTION	"below"
#define DEF_MENUBUTTON_DISABLED_FG_COLOR DISABLED
#define DEF_MENUBUTTON_DISABLED_FG_MONO	""
#define DEF_MENUBUTTON_FONT		"TkDefaultFont"
#define DEF_MENUBUTTON_FG		NORMAL_FG
#define DEF_MENUBUTTON_HEIGHT		"0"
#define DEF_MENUBUTTON_HIGHLIGHT_BG_COLOR DEF_MENUBUTTON_BG_COLOR
#define DEF_MENUBUTTON_HIGHLIGHT_BG_MONO  DEF_MENUBUTTON_BG_MONO
#define DEF_MENUBUTTON_HIGHLIGHT	BLACK
#define DEF_MENUBUTTON_HIGHLIGHT	NORMAL_BG
#define DEF_MENUBUTTON_HIGHLIGHT_WIDTH	"0"
#define DEF_MENUBUTTON_IMAGE		NULL
#define DEF_MENUBUTTON_INDICATOR	"1"
#define DEF_MENUBUTTON_JUSTIFY		"left"
#define DEF_MENUBUTTON_MENU		""
#define DEF_MENUBUTTON_PADX		"0"
#define DEF_MENUBUTTON_PADY		"0"

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
1
2
3
4
5




6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33





-
-
-
-
+
+
+
+
















-
+







/*
 * 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 <[email protected]>
 * Copyright (c) 2017 Christian Gollwitzer.
 * Copyright © 1996-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2006-2009 Daniel A. Steffen <[email protected]>
 * Copyright © 2017 Christian Gollwitzer.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkFileFilter.h"
#include "tkMacOSXConstants.h"

#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
#define modalOK     NSOKButton
#define modalCancel NSCancelButton
#else
#define modalOK     NSModalResponseOK
#define modalCancel NSModalResponseCancel
#endif // MAC_OS_X_VERSION_MIN_REQUIRED < 1090
#define modalOther  -1
#define modalOther  -1 // indicates that the -command option was used.
#define modalError  -2

/*
 * Vars for filtering in "open file" and "save file" dialogs.
 */

typedef struct {
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







+
+
+
+







    NSMutableArray *allowedExtensions;	/* Set of all allowed extensions. */
    bool allowedExtensionsAllowAll;	/* Set of all allowed extensions
					 * includes *.* */
    NSUInteger fileTypeIndex;		/* Index of currently selected
					 * filter. */
} filepanelFilterInfo;

/*
 * Only one of these is needed for the application, so they can be static.
 */

static filepanelFilterInfo filterInfo;
static NSOpenPanel *openpanel;
static NSSavePanel *savepanel;

static const char *const colorOptionStrings[] = {
    "-initialcolor", "-parent", "-title", NULL
};
246
247
248
249
250
251
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
265
266
267
268
269
270







-
-
+
+

-
+
-


+







	    }
	} else {
	    Tcl_SetObjResult(callbackInfo->interp, resultObj);
	}
    } else if (returnCode == modalCancel) {
	Tcl_ResetResult(callbackInfo->interp);
    }
    if (panel == [NSApp modalWindow]) {
	[NSApp stopModalWithCode:returnCode];
    if (callbackInfo->cmdObj) {
	Tcl_DecrRefCount(callbackInfo->cmdObj);
    }
    if (callbackInfo->cmdObj) {
    if (callbackInfo) {
	Tcl_DecrRefCount(callbackInfo->cmdObj);
	ckfree(callbackInfo);
    }
    [NSApp stopModalWithCode:returnCode];
}

- (void) tkAlertDidEnd: (NSAlert *) alert returnCode: (NSInteger) returnCode
	contextInfo: (void *) contextInfo
{
    AlertCallbackInfo *callbackInfo = contextInfo;

294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
298
299
300
301
302
303
304

305
306
307
308
309
310
311







-







	ckfree(callbackInfo);
    }
}

- (void)selectFormat:(id)sender  {
    NSPopUpButton *button      = (NSPopUpButton *)sender;
    filterInfo.fileTypeIndex   = [button indexOfSelectedItem];

    if ([[filterInfo.fileTypeAllowsAll objectAtIndex:filterInfo.fileTypeIndex] boolValue]) {
	[openpanel setAllowsOtherFileTypes:YES];

	/*
	 * setAllowsOtherFileTypes might have no effect; it's inherited from
	 * the NSSavePanel, where it has the effect that it does not append an
	 * extension. Setting the allowed file types to nil allows selecting
352
353
354
355
356
357
358









359
360
361
362
363
364
365
366



























367
368
369
370
371
372
373
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370








371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404







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







	[panel beginSheetModalForWindow:parent
	       completionHandler:^(NSModalResponse returnCode) {
	    [NSApp tkFilePanelDidEnd:panel
		       returnCode:returnCode
		       contextInfo:callbackInfo ];
	    }];

	/*
	 * The sheet has been prepared, so now we have to run it as a modal
	 * window.  Using [NSApp runModalForWindow:] on macOS 10.15 or later
	 * generates warnings on stderr.  But using [NSOpenPanel runModal] or
	 * [NSSavePanel runModal] on 10.14 or earler does not cause the
	 * completion handler to run when the panel is closed.
	 */

	if ([NSApp macOSVersion] > 101400) {
	modalReturnCode = callbackInfo->cmdObj ? modalOther :
	    [panel runModal];
    } else {
	modalReturnCode = [panel runModal];
	[NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode
		     contextInfo:callbackInfo];
    }
    return modalReturnCode;
	    modalReturnCode = [panel runModal];
	} else {
	    modalReturnCode = [NSApp runModalForWindow:panel];
	}
    } else {

	/*
	 * For the standalone file dialog, completion handlers do not work
	 * at all on macOS 10.14 and earlier.
	 */

	if ([NSApp macOSVersion] > 101400) {
	    [panel beginWithCompletionHandler:^(NSModalResponse returnCode) {
		    [NSApp tkFilePanelDidEnd:panel
			          returnCode:returnCode
			         contextInfo:callbackInfo ];
	    }];
	    modalReturnCode = [panel runModal];
	} else {
	    modalReturnCode = [panel runModal];
	    [NSApp tkFilePanelDidEnd:panel
		   	  returnCode:modalReturnCode
		         contextInfo:callbackInfo ];
	    [panel close];
	}
    }
    return callbackInfo->cmdObj ? modalOther : modalReturnCode;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_ChooseColorObjCmd --
 *
763
764
765
766
767
768
769

770
771
772
773
774
775
776
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808







+








	[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
814
815
816
817
818
819
820
821

822
823
824
825
826
827
828
846
847
848
849
850
851
852

853
854
855
856
857
858
859
860







-
+







    callbackInfo->multiple = multiple;
    if (directory || filename) {
	NSURL *fileURL = getFileURL(directory, filename);

	[openpanel setDirectoryURL:fileURL];
    }
    if (haveParentOption) {
	parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
	parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);
	parentIsKey = parent && [parent isKeyWindow];
    } else {
	parent = nil;
	parentIsKey = False;
    }
    modalReturnCode = showOpenSavePanel(openpanel, parent, callbackInfo);
    result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
866
867
868
869
870
871
872
873

874
875
876
877



878
879
880
881

882
883
884
885
886
887
888
898
899
900
901
902
903
904

905
906



907
908
909
910
911
912

913
914
915
916
917
918
919
920







-
+

-
-
-
+
+
+



-
+







	    extension = [selectedFile pathExtension];

	    if (filterInfo.preselectFilter &&
		    filterCompatible(extension, filterInfo.fileTypeIndex)) {
		selectedFilterIndex = filterInfo.fileTypeIndex;  // The preselection from the typevariable
		selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex];
	    } else {
		NSUInteger i;
		NSUInteger j;

		for (i = 0; i < [filterInfo.fileTypeNames count]; i++) {
		    if (filterCompatible(extension, i)) {
			selectedFilterIndex = i;
		for (j = 0; j < [filterInfo.fileTypeNames count]; j++) {
		    if (filterCompatible(extension, j)) {
			selectedFilterIndex = j;
			break;
		    }
		}
		if (i == selectedFilterIndex) {
		if (j == selectedFilterIndex) {
		    selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex];
		} else {
		    selectedFilter = @"";
		}
	    }
	}
	Tcl_ObjSetVar2(interp, typeVariablePtr, NULL,
913
914
915
916
917
918
919
920

921
922
923
924
925
926
927
945
946
947
948
949
950
951

952
953
954
955
956
957
958
959







-
+







int
Tk_GetSaveFileObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = clientData;
    Tk_Window tkwin = (Tk_Window)clientData;
    char *str;
    int i, result = TCL_ERROR, haveParentOption = 0;
    int confirmOverwrite = 1;
    int index, len;
    Tcl_Obj *cmdObj = NULL, *typeVariablePtr = NULL, *fileTypesPtr = NULL;
    FilePanelCallbackInfo callbackInfoStruct;
    FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct;
1048
1049
1050
1051
1052
1053
1054

1055
1056
1057
1058
1059
1060
1061
1062
1063
1080
1081
1082
1083
1084
1085
1086
1087
1088

1089
1090
1091
1092
1093
1094
1095







+

-







	[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 setTarget:NSApp];
	[popupButton setAction:@selector(saveFormat:)];

	[accessoryView addSubview:label];
	[accessoryView addSubview:popupButton];

	[savepanel setAccessoryView:accessoryView];

	[savepanel setAllowedFileTypes:[filterInfo.fileTypeExtensions objectAtIndex:filterInfo.fileTypeIndex]];
	[savepanel setAllowsOtherFileTypes:filterInfo.allowedExtensionsAllowAll];
1100
1101
1102
1103
1104
1105
1106
1107

1108
1109
1110
1111
1112
1113
1114
1132
1133
1134
1135
1136
1137
1138

1139
1140
1141
1142
1143
1144
1145
1146







-
+








    if (filename) {
	[savepanel setNameFieldStringValue:filename];
    } else {
	[savepanel setNameFieldStringValue:@""];
    }
    if (haveParentOption) {
	parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
	parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);
	parentIsKey = parent && [parent isKeyWindow];
    } else {
	parent = nil;
	parentIsKey = False;
    }
    modalReturnCode = showOpenSavePanel(savepanel, parent, callbackInfo);
    result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
1155
1156
1157
1158
1159
1160
1161
1162

1163
1164
1165
1166
1167
1168
1169
1187
1188
1189
1190
1191
1192
1193

1194
1195
1196
1197
1198
1199
1200
1201







-
+







int
Tk_ChooseDirectoryObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = clientData;
    Tk_Window tkwin = (Tk_Window)clientData;
    char *str;
    int i, result = TCL_ERROR, haveParentOption = 0;
    int index, len, mustexist = 0;
    Tcl_Obj *cmdObj = NULL;
    FilePanelCallbackInfo callbackInfoStruct;
    FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct;
    NSString *directory = nil;
1242
1243
1244
1245
1246
1247
1248
1249

1250
1251
1252

1253
1254
1255
1256
1257
1258
1259
1274
1275
1276
1277
1278
1279
1280

1281
1282
1283

1284
1285
1286
1287
1288
1289
1290
1291







-
+


-
+







     * Check for directory value, set to root if not specified; otherwise
     * crashes with exception because of nil string parameter.
     */

    if (!directory) {
	directory = @"/";
    }
    parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
    parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);
    [panel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]];
    if (haveParentOption) {
	parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
	parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);
	parentIsKey = parent && [parent isKeyWindow];
    } else {
	parent = nil;
	parentIsKey = False;
    }
    modalReturnCode = showOpenSavePanel(panel, parent, callbackInfo);
    result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
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
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







-
-
-
+
-
-
-
-
-
+

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


















-
+




-
-




-
+







 *
 *----------------------------------------------------------------------
 */

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.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	none
 *
 *----------------------------------------------------------------------
 */

int
TkMacOSXStandardAboutPanelObjCmd(
    ClientData dummy,	/* Unused. */
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    (void)dummy;

    if (objc > 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }
    TkAboutDlg();
    [NSApp orderFrontStandardAboutPanel:nil];
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MessageBoxObjCmd --
1393
1394
1395
1396
1397
1398
1399
1400

1401
1402
1403
1404
1405
1406
1407
1368
1369
1370
1371
1372
1373
1374

1375
1376
1377
1378
1379
1380
1381
1382







-
+







int
Tk_MessageBoxObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = clientData;
    Tk_Window tkwin = (Tk_Window)clientData;
    char *str;
    int i, result = TCL_ERROR, haveParentOption = 0;
    int index, typeIndex, iconIndex, indexDefaultOption = 0;
    int defaultNativeButtonIndex = 1; /* 1, 2, 3: right to left */
    Tcl_Obj *cmdObj = NULL;
    AlertCallbackInfo callbackInfoStruct, *callbackInfo = &callbackInfoStruct;
    NSString *message, *title;
1531
1532
1533
1534
1535
1536
1537
1538

1539
1540
1541
1542
1543
1544
1545
1506
1507
1508
1509
1510
1511
1512

1513
1514
1515
1516
1517
1518
1519
1520







-
+







	}
	Tcl_IncrRefCount(cmdObj);
    }
    callbackInfo = (AlertCallbackInfo *)ckalloc(sizeof(AlertCallbackInfo));
    callbackInfo->cmdObj = cmdObj;
    callbackInfo->interp = interp;
    callbackInfo->typeIndex = typeIndex;
    parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
    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
1652
1653
1654
1655
1656
1657
1658
1659

1660
1661
1662
1663
1664
1665
1666
1667
1668

1669
1670
1671
1672
1673
1674
1675
1627
1628
1629
1630
1631
1632
1633

1634
1635
1636
1637
1638
1639
1640
1641
1642

1643
1644
1645
1646
1647
1648
1649
1650







-
+








-
+








    if (![fontPanelFontAttributes isEqual:attributes]) {
	[fontPanelFontAttributes setDictionary:attributes];
	FontchooserEvent(FontchooserSelection);
    }
}

- (NSUInteger) validModesForFontPanel: (NSFontPanel *) fontPanel
- (NSUInteger) validModesForFontPanel: (NSFontPanel *)fontPanel
{
    (void)fontPanel;

    return (NSFontPanelStandardModesMask & ~NSFontPanelAllEffectsModeMask) |
	    NSFontPanelUnderlineEffectModeMask |
	    NSFontPanelStrikethroughEffectModeMask;
}

- (void) windowDidOrderOffScreen: (NSNotification *) notification
- (void) windowDidOrderOffScreen: (NSNotification *)notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    if ([[notification object] isEqual:[[NSFontManager sharedFontManager]
	    fontPanel:NO]]) {
	FontchooserEvent(FontchooserClosed);
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
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







-
+


















-
+







 *	This processes events generated by user interaction with the font
 *	panel.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Additional events may be place on the Tk event queue.
 *	Additional events may be placed on the Tk event queue.
 *
 *----------------------------------------------------------------------
 */

static void
FontchooserEvent(
    int kind)
{
    FontchooserData *fcdPtr;
    Tcl_Obj *fontObj;

    if (!fontchooserInterp) {
	return;
    }
    fcdPtr = Tcl_GetAssocData(fontchooserInterp, "::tk::fontchooser", NULL);
    switch (kind) {
    case FontchooserClosed:
	if (fcdPtr->parent != None) {
	    TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility", NULL);
	    Tk_SendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility", NULL);
	    fontchooserInterp = NULL;
	}
	break;
    case FontchooserSelection:
	fontObj = TkMacOSXFontDescriptionForNSFontAndNSFontAttributes(
		fontPanelFont, fontPanelFontAttributes);
	if (fontObj) {
1727
1728
1729
1730
1731
1732
1733
1734

1735
1736
1737
1738
1739
1740
1741
1702
1703
1704
1705
1706
1707
1708

1709
1710
1711
1712
1713
1714
1715
1716







-
+







		    memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc);
		    tmpv[objc] = fontObj;
		    TkBackgroundEvalObjv(fontchooserInterp, objc + 1, tmpv,
			    TCL_EVAL_GLOBAL);
		    ckfree(tmpv);
		}
	    }
	    TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserFontChanged", NULL);
	    Tk_SendVirtualEvent(fcdPtr->parent, "TkFontchooserFontChanged", NULL);
	}
	break;
    }
}

/*
 *----------------------------------------------------------------------
1761
1762
1763
1764
1765
1766
1767
1768

1769
1770
1771
1772
1773
1774
1775
1736
1737
1738
1739
1740
1741
1742

1743
1744
1745
1746
1747
1748
1749
1750







-
+







{
    Tcl_Obj *resObj = NULL;

    switch(optionIndex) {
    case FontchooserParent:
	if (fcdPtr->parent != None) {
	    resObj = Tcl_NewStringObj(
		    ((TkWindow *) fcdPtr->parent)->pathName, -1);
		    ((TkWindow *)fcdPtr->parent)->pathName, -1);
	} else {
	    resObj = Tcl_NewStringObj(".", 1);
	}
	break;
    case FontchooserTitle:
	if (fcdPtr->titleObj) {
	    resObj = fcdPtr->titleObj;
1936
1937
1938
1939
1940
1941
1942
1943

1944
1945
1946
1947
1948
1949
1950
1911
1912
1913
1914
1915
1916
1917

1918
1919
1920
1921
1922
1923
1924
1925







-
+







	    NSFontPanel *fp = [fm fontPanel:NO];

	    [fp setPanelFont:fontPanelFont isMultiple:NO];
	    [fm setSelectedFont:fontPanelFont isMultiple:NO];
	    [fm setSelectedAttributes:fontPanelFontAttributes
		    isMultiple:NO];
	    if ([fp isVisible]) {
		TkSendVirtualEvent(fcdPtr->parent,
		Tk_SendVirtualEvent(fcdPtr->parent,
			"TkFontchooserFontChanged", NULL);
	    }
	    break;
	case FontchooserCmd:
	    if (fcdPtr->cmdObj) {
		Tcl_DecrRefCount(fcdPtr->cmdObj);
	    }
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
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







-
-
+
+



-
-


-
+












-
+







 * ----------------------------------------------------------------------
 */

static int
FontchooserShowCmd(
    ClientData clientData,	/* Main window */
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
    TCL_UNUSED(int),
    TCL_UNUSED(Tcl_Obj *const *))
{
    FontchooserData *fcdPtr = Tcl_GetAssocData(interp, "::tk::fontchooser",
	    NULL);
    (void)objc;
    (void)objv;

    if (fcdPtr->parent == None) {
	fcdPtr->parent = (Tk_Window) clientData;
	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];
	TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility", NULL);
	Tk_SendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility", NULL);
    }
    fontchooserInterp = interp;

    return TCL_OK;
}

/*
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040




2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2003
2004
2005
2006
2007
2008
2009




2010
2011
2012
2013
2014
2015




2016
2017
2018
2019
2020
2021
2022







-
-
-
-
+
+
+
+


-
-
-
-







 *	Font Panel may be hidden.
 *
 * ----------------------------------------------------------------------
 */

static int
FontchooserHideCmd(
    ClientData dummy,	/* Main window */
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
    TCL_UNUSED(void *),	/* Main window */
    TCL_UNUSED(Tcl_Interp *),
    TCL_UNUSED(int),
    TCL_UNUSED(Tcl_Obj *const *))
{
    NSFontPanel *fp = [[NSFontManager sharedFontManager] fontPanel:NO];
    (void)dummy;
    (void)interp;
    (void)objc;
    (void)objv;

    if ([fp isVisible]) {
	[fp orderOut:NSApp];
    }
    return TCL_OK;
}

2136
2137
2138
2139
2140
2141
2142
2143

2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2105
2106
2107
2108
2109
2110
2111

2112
2113
2114

2115
2116
2117
2118
2119
2120
2121







-
+


-







 *
 * ----------------------------------------------------------------------
 */

MODULE_SCOPE int
TkInitFontchooser(
    Tcl_Interp *interp,
    ClientData dummy)
    TCL_UNUSED(void *))
{
    FontchooserData *fcdPtr = (FontchooserData *)ckalloc(sizeof(FontchooserData));
    (void)dummy;

    bzero(fcdPtr, sizeof(FontchooserData));
    Tcl_SetAssocData(interp, "::tk::fontchooser", DeleteFontchooserData,
	    fcdPtr);
    if (!fontPanelFontAttributes) {
	fontPanelFontAttributes = [NSMutableDictionary new];
    }

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
1
2
3


4
5
6




7
8
9
10
11
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27



-
-
+
+

-
-
-
-
+
+
+
+









-
+







/*
 * tkMacOSXDraw.c --
 *
 *	This file contains functions that perform drawing to Xlib windows. Most
 *	of the functions simply emulate Xlib functions.
 *	This file contains functions that draw to windows. Many of thees
 *	functions emulate Xlib functions.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <[email protected]>
 * Copyright 2014 Marc Culler.
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2006-2009 Daniel A. Steffen <[email protected]>
 * 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 >= 101400
#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
39
40
41
42
43
44
45

46
47
48
49
50
51


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

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

87
88
89
90
91
92
93
94
95
96

97
98
99
100

101
102

103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

131
132
133
134
135
136
137

138
139
140
141
142
143

144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168


169
170
171
172
173
174
175


176
177
178
179
180
181
182

183
184
185
186
187


188
189
190
191
192
193
194

195
196
197
198
199

200
201
202
203



204
205
206
207






208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335

336
337

338
339
340

341
342
343
344

345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425

426
427
428
429
430
431
432
433
434
435







436

437
438



439
440
441
442
443








444
445
446
447
448
449

450
451
452
453
454
455
456
457
458
459
460
461
462
463

464
465
466
467
468
469
470

471

472




473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560

561
562
563
564
565
566
567
568
569
570
571
572
573
574


575
576
577

578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595

596
597
598
599
600
601
602
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

75
76
77
78

79
80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95
96
97

98
99
100
101

102
103
104
105
106
107
108
109
110
111
112

113
114



















115

116
117




118



119
120

121
122
123
124


















125



126
127







128
129







130





131
132







133





134




135
136
137




138
139
140
141
142
143
144
145
146
147
148



























































































































149


150



151




152















































































153

154
155
156
157
158
159
160
161



162
163
164
165
166
167
168
169
170


171
172
173
174




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

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

202
203
204
205
206
207
208
209
210
211
212

213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228












































































229
230
231
232
233
234
235
236
237
238
239
240
241


242
243
244
245

246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263

264
265
266
267
268
269
270
271







+






+
+




















-
+



-









-
+









-
+



-
+


+







-
+

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


-
-
-
-
+
-
-
-


-
+



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

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





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

-
+







-
-
-
+
+
+
+
+
+
+

+
-
-
+
+
+

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





-
+













-
+







+

+
-
+
+
+
+












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












-
-
+
+


-
+

















-
+







#define NON_AA_CG_OFFSET .999

static int cgAntiAliasLimit = 0;
#define notAA(w)	((w) < cgAntiAliasLimit)

static int useThemedToplevel = 0;
static int useThemedFrame = 0;
static unsigned long transparentColor;

/*
 * Prototypes for functions used only in this file.
 */

static void ClipToGC(Drawable d, GC gc, HIShapeRef *clipRgnPtr);
static NSImage *CreateNSImageFromPixmap(Pixmap pixmap, int width, int height);


/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXInitCGDrawing --
 *
 *	Initializes link vars that control CG drawing.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE int
TkMacOSXInitCGDrawing(
    Tcl_Interp *interp,
    int enable,
    TCL_UNUSED(int),
    int limit)
{
    static Boolean initialized = FALSE;
    (void)enable;

    if (!initialized) {
	initialized = TRUE;

	if (Tcl_CreateNamespace(interp, "::tk::mac", NULL, NULL) == NULL) {
	    Tcl_ResetResult(interp);
	}

	if (Tcl_LinkVar(interp, "::tk::mac::CGAntialiasLimit",
		(char *) &cgAntiAliasLimit, TCL_LINK_INT) != TCL_OK) {
		(char *)&cgAntiAliasLimit, TCL_LINK_INT) != TCL_OK) {
	    Tcl_ResetResult(interp);
	}
	cgAntiAliasLimit = limit;

	/*
	 * Piggy-back the themed drawing var init here.
	 */

	if (Tcl_LinkVar(interp, "::tk::mac::useThemedToplevel",
		(char *) &useThemedToplevel, TCL_LINK_BOOLEAN) != TCL_OK) {
		(char *)&useThemedToplevel, TCL_LINK_BOOLEAN) != TCL_OK) {
	    Tcl_ResetResult(interp);
	}
	if (Tcl_LinkVar(interp, "::tk::mac::useThemedFrame",
		(char *) &useThemedFrame, TCL_LINK_BOOLEAN) != TCL_OK) {
		(char *)&useThemedFrame, TCL_LINK_BOOLEAN) != TCL_OK) {
	    Tcl_ResetResult(interp);
	}
	transparentColor = TkMacOSXClearPixel();
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXBitmapRepFromDrawableRect
 * TkMacOSXGetNSImageFromTkImage --
 *
 *	Extract bitmap data from a MacOSX drawable as an NSBitmapImageRep.
 *
 *      This is only used by XGetImage, which is never called.  And this
 *      implementation does not work correctly.  Originally it relied on
 *      [NSBitmapImageRep initWithFocusedViewRect:view_rect] which was
 *      deprecated by Apple in OSX 10.14 and also required the use of other
 *      deprecated functions such as [NSView lockFocus]. Apple's suggested
 *      replacement is [NSView cacheDisplayInRect: toBitmapImageRep:] and that
 *      is what is being used here.  However, that method only works when the
 *      view has a valid CGContext, and a view is only guaranteed to have a
 *      valid context during a call to [NSView drawRect]. To further complicate
 *      matters, cacheDisplayInRect calls [NSView drawRect]. Essentially it is
 *      asking the view to draw a subrectangle of itself into a special
 *      graphics context which is linked to the BitmapImageRep. But our
 *      implementation of [NSView drawRect] does not allow recursive calls. If
 *      called recursively it returns immediately without doing any drawing.
 *      So the bottom line is that this function either returns a NULL pointer
 *      or a black image. To make it useful would require a significant amount
 *      of rewriting of the drawRect method. Perhaps the next release of OSX
 *	Get autoreleased NSImage for Tk_Image.
 *      will include some more helpful ways of doing this.
 *
 * Results:
 *	Returns an NSBitmapRep representing the image of the given rectangle of
 *      the given drawable. This object is retained. The caller is responsible
 *      for releasing it.
 *
 *	NSImage.
 *      NOTE: The x,y coordinates should be relative to a coordinate system
 *      with origin at the top left, as used by XImage and CGImage, not bottom
 *      left as used by NSView.
 *
 * Side effects:
 *     None
 *	None.
 *
 *----------------------------------------------------------------------
 */

NSBitmapImageRep *
TkMacOSXBitmapRepFromDrawableRect(
    Drawable drawable,
    int x,
    int y,
    unsigned int width,
    unsigned int height)
{
    MacDrawable *mac_drawable = (MacDrawable *) drawable;
    CGContextRef cg_context = NULL;
    CGImageRef cg_image = NULL, sub_cg_image = NULL;
    NSBitmapImageRep *bitmap_rep = NULL;
    NSView *view = NULL;
    if (mac_drawable->flags & TK_IS_PIXMAP) {
	/*
	 * This MacDrawable is a bitmap, so its view is NULL.
	 */

	CGRect image_rect = CGRectMake(x, y, width, height);

	cg_context = TkMacOSXGetCGContextForDrawable(drawable);
NSImage *
TkMacOSXGetNSImageFromTkImage(
	cg_image = CGBitmapContextCreateImage((CGContextRef) cg_context);
	sub_cg_image = CGImageCreateWithImageInRect(cg_image, image_rect);
	if (sub_cg_image) {
	    bitmap_rep = [NSBitmapImageRep alloc];
	    [bitmap_rep initWithCGImage:sub_cg_image];
	}
	if (cg_image) {
    Display *display,
    Tk_Image image,
	    CGImageRelease(cg_image);
	}
    } else if ((view = TkMacOSXDrawableView(mac_drawable)) != NULL) {
	/*
	 * Convert Tk top-left to NSView bottom-left coordinates.
	 */

    int width,
	int view_height = [view bounds].size.height;
	NSRect view_rect = NSMakeRect(x + mac_drawable->xOff,
		view_height - height - y - mac_drawable->yOff,
		width, height);

    int height)
{
	/*
	 * Attempt to copy from the view to a bitmapImageRep.  If the view does
	 * not have a valid CGContext, doing this will silently corrupt memory
	 * and make a big mess. So, in that case, we mark the view as needing
	 * display and return NULL.
	 */

    Pixmap pixmap;
	if (view == [NSView focusView]) {
	    bitmap_rep = [view bitmapImageRepForCachingDisplayInRect: view_rect];
	    [bitmap_rep retain];
	    [view cacheDisplayInRect:view_rect toBitmapImageRep:bitmap_rep];
	} else {
    NSImage *nsImage;
	    TkMacOSXDbgMsg("No CGContext - cannot copy from screen to bitmap.");
	    [view setNeedsDisplay:YES];
	    return NULL;
	}
    if (width == 0 || height == 0) {
	return nsImage = [[NSImage alloc] initWithSize:NSMakeSize(0,0)];
    }
    } else {
	TkMacOSXDbgMsg("Invalid source drawable");
    }
    return bitmap_rep;
    pixmap = Tk_GetPixmap(display, None, width, height, 0);
    Tk_RedrawImage(image, 0, 0, width, height, pixmap, 0, 0);
    nsImage = CreateNSImageFromPixmap(pixmap, width, height);
    Tk_FreePixmap(display, pixmap);

    return [nsImage autorelease];
}

/*
 *----------------------------------------------------------------------
 *
 * XCopyArea --
 *
 *	Copies data from one drawable to another.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Data is moved from a window or bitmap to a second window or bitmap.
 *
 *----------------------------------------------------------------------
 */

int
XCopyArea(
    Display *display,		/* Display. */
    Drawable src,		/* Source drawable. */
    Drawable dst,		/* Destination drawable. */
    GC gc,			/* GC to use. */
    int src_x,			/* X & Y, width & height */
    int src_y,			/* define the source rectangle */
    unsigned int width,		/* that will be copied. */
    unsigned int height,
    int dest_x,			/* Dest X & Y on dest rect. */
    int dest_y)
{
    TkMacOSXDrawingContext dc;
    MacDrawable *srcDraw = (MacDrawable *) src;
    NSBitmapImageRep *bitmap_rep = NULL;
    CGImageRef img = NULL;
    CGRect bounds, srcRect, dstRect;

    display->request++;
    if (!width || !height) {
	return BadDrawable;
    }

    if (!TkMacOSXSetupDrawingContext(dst, gc, 1, &dc)) {
	TkMacOSXDbgMsg("Failed to setup drawing context.");
	return BadDrawable;
    }

    if (!dc.context) {
	TkMacOSXDbgMsg("Invalid destination drawable - no context.");
	return BadDrawable;
    }

    if (srcDraw->flags & TK_IS_PIXMAP) {
	img = TkMacOSXCreateCGImageWithDrawable(src);
    } else if (TkMacOSXDrawableWindow(src)) {
	bitmap_rep = TkMacOSXBitmapRepFromDrawableRect(src,
		src_x, src_y, width, height);
	if (bitmap_rep) {
	    img = [bitmap_rep CGImage];
	}
    } else {
	TkMacOSXDbgMsg("Invalid source drawable - neither window nor pixmap.");
    }

    if (img) {
	bounds = CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height);
	srcRect = CGRectMake(src_x, src_y, width, height);
	dstRect = CGRectMake(dest_x, dest_y, width, height);
	TkMacOSXDrawCGImage(dst, gc, dc.context, img,
		gc->foreground, gc->background, bounds, srcRect, dstRect);
	CFRelease(img);
    } else {
	TkMacOSXDbgMsg("Failed to construct CGImage.");
    }

    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XCopyPlane --
 *
 *	Copies a bitmap from a source drawable to a destination drawable. The
 *	plane argument specifies which bit plane of the source contains the
 *	bitmap. Note that this implementation ignores the gc->function.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Changes the destination drawable.
 *
 *----------------------------------------------------------------------
 */

int
XCopyPlane(
    Display *display,		/* Display. */
    Drawable src,		/* Source drawable. */
    Drawable dst,		/* Destination drawable. */
    GC gc,				/* GC to use. */
    int src_x,			/* X & Y, width & height */
    int src_y,			/* define the source rectangle */
    unsigned int width,	/* that will be copied. */
    unsigned int height,
    int dest_x,			/* Dest X & Y on dest rect. */
    int dest_y,
    unsigned long plane)	/* Which plane to copy. */
{
    TkMacOSXDrawingContext dc;
    MacDrawable *srcDraw = (MacDrawable *) src;
    MacDrawable *dstDraw = (MacDrawable *) dst;
    CGRect bounds, srcRect, dstRect;
    display->request++;
    if (!width || !height) {
	/* TkMacOSXDbgMsg("Drawing of empty area requested"); */
	return BadDrawable;
    }
    if (plane != 1) {
	Tcl_Panic("Unexpected plane specified for XCopyPlane");
    }
    if (srcDraw->flags & TK_IS_PIXMAP) {
	if (!TkMacOSXSetupDrawingContext(dst, gc, 1, &dc)) {
	    return BadDrawable;
	}

 * TkMacOSXGetNSImageFromBitmap --
	CGContextRef context = dc.context;

 *
	if (context) {
	    CGImageRef img = TkMacOSXCreateCGImageWithDrawable(src);

 *	Get autoreleased NSImage for Bitmap.
	    if (img) {
		TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask;
		unsigned long imageBackground  = gc->background;

 *
                if (clipPtr && clipPtr->type == TKP_CLIP_PIXMAP) {
		    srcRect = CGRectMake(src_x, src_y, width, height);
		    CGImageRef mask = TkMacOSXCreateCGImageWithDrawable(
			    clipPtr->value.pixmap);
		    CGImageRef submask = CGImageCreateWithImageInRect(
			    img, srcRect);
		    CGRect rect = CGRectMake(dest_x, dest_y, width, height);

		    rect = CGRectOffset(rect, dstDraw->xOff, dstDraw->yOff);
		    CGContextSaveGState(context);

		    /*
		     * Move the origin of the destination to top left.
		     */

		    CGContextTranslateCTM(context,
			    0, rect.origin.y + CGRectGetMaxY(rect));
		    CGContextScaleCTM(context, 1, -1);

		    /*
		     * Fill with the background color, clipping to the mask.
		     */

		    CGContextClipToMask(context, rect, submask);
		    TkMacOSXSetColorInContext(gc, gc->background, dc.context);
		    CGContextFillRect(context, rect);

		    /*
		     * Fill with the foreground color, clipping to the
		     * intersection of img and mask.
		     */

		    CGImageRef subimage = CGImageCreateWithImageInRect(
			    img, srcRect);
		    CGContextClipToMask(context, rect, subimage);
		    TkMacOSXSetColorInContext(gc, gc->foreground, context);
		    CGContextFillRect(context, rect);
		    CGContextRestoreGState(context);
		    CGImageRelease(img);
		    CGImageRelease(mask);
		    CGImageRelease(submask);
		    CGImageRelease(subimage);
		} else {
		    bounds = CGRectMake(0, 0,
			    srcDraw->size.width, srcDraw->size.height);
		    srcRect = CGRectMake(src_x, src_y, width, height);
		    dstRect = CGRectMake(dest_x, dest_y, width, height);
		    TkMacOSXDrawCGImage(dst, gc, dc.context, img,
			    gc->foreground, imageBackground, bounds,
			    srcRect, dstRect);
		    CGImageRelease(img);
		}
	    } else {
		/* no image */
		TkMacOSXDbgMsg("Invalid source drawable");
	    }
	} else {
	    TkMacOSXDbgMsg("Invalid destination drawable - "
		    "could not get a bitmap context.");
	}
	TkMacOSXRestoreDrawingContext(&dc);
	return Success;
    } else {
	/*
	 * Source drawable is a Window, not a Pixmap.
	 */

	return XCopyArea(display, src, dst, gc, src_x, src_y, width, height,
		dest_x, dest_y);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXCreateCGImageWithDrawable --
 *
 *	Create a CGImage from the given Drawable.
 *
 * Results:
 *	CGImage, release after use.
 *	NSImage.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

CGImageRef
TkMacOSXCreateCGImageWithDrawable(
    Drawable drawable)
NSImage *
TkMacOSXGetNSImageFromBitmap(
    Display *display,
    Pixmap bitmap,
    GC gc,
    int width,
    int height)
{
    Pixmap pixmap = Tk_GetPixmap(display, None, width, height, 0);
    CGImageRef img = NULL;
    CGContextRef context = TkMacOSXGetCGContextForDrawable(drawable);
    NSImage *nsImage;

    unsigned long origBackground = gc->background;

    if (context) {
	img = CGBitmapContextCreateImage(context);
    }
    return img;
    gc->background = transparentColor;
    XSetClipOrigin(display, gc, 0, 0);
    XCopyPlane(display, bitmap, pixmap, gc, 0, 0, width, height, 0, 0, 1);
    gc->background = origBackground;
    nsImage = CreateNSImageFromPixmap(pixmap, width, height);
    Tk_FreePixmap(display, pixmap);

    return [nsImage autorelease];
}

/*
 *----------------------------------------------------------------------
 *
 * CreateNSImageWithPixmap --
 * CreateNSImageFromPixmap --
 *
 *	Create NSImage for Pixmap.
 *
 * Results:
 *	NSImage.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static NSImage *
CreateNSImageWithPixmap(
CreateNSImageFromPixmap(
    Pixmap pixmap,
    int width,
    int height)
{
    CGImageRef cgImage;
    NSImage *nsImage;
    NSBitmapImageRep *bitmapImageRep;
    CGContextRef context = TkMacOSXGetCGContextForDrawable(pixmap);

    if (context) {
    cgImage = TkMacOSXCreateCGImageWithDrawable(pixmap);
	cgImage = CGBitmapContextCreateImage(context);
    } else {
	return NULL;
    }
    nsImage = [[NSImage alloc] initWithSize:NSMakeSize(width, height)];
    bitmapImageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage];
    [nsImage addRepresentation:bitmapImageRep];
    [bitmapImageRep release];
    CFRelease(cgImage);

    return nsImage;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetNSImageWithTkImage --
 *
 *	Get autoreleased NSImage for Tk_Image.
 *
 * Results:
 *	NSImage.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

NSImage *
TkMacOSXGetNSImageWithTkImage(
    Display *display,
    Tk_Image image,
    int width,
    int height)
{
    Pixmap pixmap;
    NSImage *nsImage;
    if (width == 0 || height == 0) {
	return nsImage = [[NSImage alloc] initWithSize:NSMakeSize(0,0)];
    }
    pixmap = Tk_GetPixmap(display, None, width, height, 0);
    Tk_RedrawImage(image, 0, 0, width, height, pixmap, 0, 0);
    nsImage = CreateNSImageWithPixmap(pixmap, width, height);
    Tk_FreePixmap(display, pixmap);

    return [nsImage autorelease];
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetNSImageWithBitmap --
 *
 *	Get autoreleased NSImage for Bitmap.
 *
 * Results:
 *	NSImage.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

NSImage *
TkMacOSXGetNSImageWithBitmap(
    Display *display,
    Pixmap bitmap,
    GC gc,
    int width,
    int height)
{
    Pixmap pixmap = Tk_GetPixmap(display, None, width, height, 0);
    NSImage *nsImage;

    unsigned long origBackground = gc->background;

    gc->background = TRANSPARENT_PIXEL << 24;
    XSetClipOrigin(display, gc, 0, 0);
    XCopyPlane(display, bitmap, pixmap, gc, 0, 0, width, height, 0, 0, 1);
    gc->background = origBackground;
    nsImage = CreateNSImageWithPixmap(pixmap, width, height);
    Tk_FreePixmap(display, pixmap);

    return [nsImage autorelease];
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetCGContextForDrawable --
 * Tk_MacOSXGetCGContextForDrawable --
 *
 *	Get CGContext for given Drawable, creating one if necessary.
 *
 * Results:
 *	CGContext.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

CGContextRef
TkMacOSXGetCGContextForDrawable(
void *
Tk_MacOSXGetCGContextForDrawable(
    Drawable drawable)
{
    MacDrawable *macDraw = (MacDrawable *) 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;
	    bitmapInfo = (CGBitmapInfo)kCGImageAlphaOnly;
	} else {
	    colorspace = CGColorSpaceCreateDeviceRGB();
	    bitsPerPixel = 32;
	    bitmapInfo |= kCGImageAlphaPremultipliedFirst;
	}
	bytesPerRow = ((size_t)
		macDraw->size.width * bitsPerPixel + 127) >> 3 & ~15;
641
642
643
644
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
310
311
312
313
314
315
316

317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340

341
342
343
344
345

346
347
348
349
350
351
352
353







-
+

















+





-
+




-
+







    CGImageRef image,
    unsigned long imageForeground,
    unsigned long imageBackground,
    CGRect imageBounds,
    CGRect srcBounds,
    CGRect dstBounds)
{
    MacDrawable *macDraw = (MacDrawable *) d;
    MacDrawable *macDraw = (MacDrawable *)d;

    if (macDraw && context && image) {
	CGImageRef subImage = NULL;

	if (!CGRectEqualToRect(imageBounds, srcBounds)) {
	    if (!CGRectContainsRect(imageBounds, srcBounds)) {
		TkMacOSXDbgMsg("Mismatch of sub CGImage bounds");
	    }
	    subImage = CGImageCreateWithImageInRect(image, CGRectOffset(
		    srcBounds, -imageBounds.origin.x, -imageBounds.origin.y));
	    if (subImage) {
		image = subImage;
	    }
	}
	dstBounds = CGRectOffset(dstBounds, macDraw->xOff, macDraw->yOff);
	if (CGImageIsMask(image)) {
	    if (macDraw->flags & TK_IS_BW_PIXMAP) {

		/*
		 * Set fill color to black; background comes from the context,
		 * or is transparent.
		 */

		if (imageBackground != TRANSPARENT_PIXEL << 24) {
		if (imageBackground != transparentColor) {
		    CGContextClearRect(context, dstBounds);
		}
		CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0);
	    } else {
		if (imageBackground != TRANSPARENT_PIXEL << 24) {
		if (imageBackground != transparentColor) {
		    TkMacOSXSetColorInContext(gc, imageBackground, context);
		    CGContextFillRect(context, dstBounds);
		}
		TkMacOSXSetColorInContext(gc, imageForeground, context);
	    }
	}

736
737
738
739
740
741
742
743

744
745
746
747
748
749
750
751
752

753
754
755
756
757
758
759
406
407
408
409
410
411
412

413
414
415
416
417
418
419
420
421

422
423
424
425
426
427
428
429







-
+








-
+







    Display *display,		/* Display. */
    Drawable d,			/* Draw on this. */
    GC gc,			/* Use this GC. */
    XPoint *points,		/* Array of points. */
    int npoints,		/* Number of points. */
    int mode)			/* Line drawing mode. */
{
    MacDrawable *macWin = (MacDrawable *) d;
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    int i, lw = gc->line_width;

    if (npoints < 2) {
	return BadValue;
    }

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	double prevx, prevy;
	double o = (lw % 2) ? .5 : 0;

	CGContextBeginPath(dc.context);
808
809
810
811
812
813
814
815

816
817
818
819
820

821
822
823
824
825
826
827
478
479
480
481
482
483
484

485
486
487
488
489

490
491
492
493
494
495
496
497







-
+




-
+







XDrawSegments(
    Display *display,
    Drawable d,
    GC gc,
    XSegment *segments,
    int nsegments)
{
    MacDrawable *macWin = (MacDrawable *) d;
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    int i, lw = gc->line_width;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	double o = (lw % 2) ? .5 : 0;

	for (i = 0; i < nsegments; i++) {
	    CGContextBeginPath(dc.context);
857
858
859
860
861
862
863
864

865
866
867

868
869
870
871
872
873

874
875
876
877
878
879
880
527
528
529
530
531
532
533

534
535
536

537
538
539

540
541

542
543
544
545
546
547
548
549







-
+


-
+


-


-
+







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. */
    int shape,			/* Shape to draw. */
    TCL_UNUSED(int),	/* Shape to draw. */
    int mode)			/* Drawing mode. */
{
    MacDrawable *macWin = (MacDrawable *) d;
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    int i;
    (void)shape;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	double prevx, prevy;
	double o = (gc->line_width % 2) ? .5 : 0;

	CGContextBeginPath(dc.context);
919
920
921
922
923
924
925
926

927
928
929
930
931
932
933
934
935

936
937
938
939
940
941
942
588
589
590
591
592
593
594

595
596
597
598
599
600
601
602
603

604
605
606
607
608
609
610
611







-
+








-
+







    Display *display,		/* Display. */
    Drawable d,			/* Draw on this. */
    GC gc,			/* Use this GC. */
    int x, int y,		/* Upper left corner. */
    unsigned int width,		/* Width & height of rect. */
    unsigned int height)
{
    MacDrawable *macWin = (MacDrawable *) d;
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    int lw = gc->line_width;

    if (width == 0 || height == 0) {
	return BadDrawable;
    }

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;

	rect = CGRectMake(
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
640
641
642
643
644
645
646

647
648
649
650
651

652
653
654
655
656
657

658
659
660
661
662
663
664
665







-
+




-
+





-
+







 *
 *----------------------------------------------------------------------
 */

int
XDrawRectangles(
    Display *display,
    Drawable drawable,
    Drawable d,
    GC gc,
    XRectangle *rectArr,
    int nRects)
{
    MacDrawable *macWin = (MacDrawable *) drawable;
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    XRectangle * rectPtr;
    int i, lw = gc->line_width;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(drawable, gc, 1, &dc)) {
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;

	for (i = 0, rectPtr = rectArr; i < nRects; i++, rectPtr++) {
1028
1029
1030
1031
1032
1033
1034
1035

1036
1037
1038
1039
1040
1041

1042
1043
1044
1045
1046
1047
1048
697
698
699
700
701
702
703

704
705
706
707
708
709

710
711
712
713
714
715
716
717







-
+





-
+







XFillRectangles(
    Display *display,		/* Display. */
    Drawable d,			/* Draw on this. */
    GC gc,			/* Use this GC. */
    XRectangle *rectangles,	/* Rectangle array. */
    int n_rectangles)		/* Number of rectangles. */
{
    MacDrawable *macWin = (MacDrawable *) d;
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    XRectangle * rectPtr;
    int i;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;

	for (i = 0, rectPtr = rectangles; i < n_rectangles; i++, rectPtr++) {
	    if (rectPtr->width == 0 || rectPtr->height == 0) {
1087
1088
1089
1090
1091
1092
1093
1094

1095
1096
1097
1098
1099
1100
1101
756
757
758
759
760
761
762

763
764
765
766
767
768
769
770







-
+







    int inset,
    int thickness)
{
    Drawable d = Tk_WindowId(tkwin);
    TkMacOSXDrawingContext dc;
    CGRect outerRect, innerRect;

    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return;
    }
    if (dc.context) {
	outerRect = CGRectMake(Tk_X(tkwin), Tk_Y(tkwin),
			       Tk_Width(tkwin), Tk_Height(tkwin));
	outerRect = CGRectInset(outerRect, inset, inset);
	innerRect = CGRectInset(outerRect, thickness, thickness);
1130
1131
1132
1133
1134
1135
1136
1137

1138
1139
1140
1141
1142
1143
1144
1145
1146

1147
1148
1149
1150
1151
1152
1153
799
800
801
802
803
804
805

806
807
808
809
810
811
812
813
814

815
816
817
818
819
820
821
822







-
+








-
+







    GC gc,			/* Use this GC. */
    int x, int y,		/* Upper left of bounding rect. */
    unsigned int width,		/* Width & height. */
    unsigned int height,
    int angle1,			/* Staring angle of arc. */
    int angle2)			/* Extent of arc. */
{
    MacDrawable *macWin = (MacDrawable *) d;
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    int lw = gc->line_width;

    if (width == 0 || height == 0 || angle2 == 0) {
	return BadDrawable;
    }

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;

	rect = CGRectMake(
1203
1204
1205
1206
1207
1208
1209
1210

1211
1212
1213
1214
1215
1216

1217
1218
1219
1220
1221
1222
1223
872
873
874
875
876
877
878

879
880
881
882
883
884

885
886
887
888
889
890
891
892







-
+





-
+







XDrawArcs(
    Display *display,
    Drawable d,
    GC gc,
    XArc *arcArr,
    int nArcs)
{
    MacDrawable *macWin = (MacDrawable *) d;
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    XArc *arcPtr;
    int i, lw = gc->line_width;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;

	for (i=0, arcPtr = arcArr; i < nArcs; i++, arcPtr++) {
1281
1282
1283
1284
1285
1286
1287
1288

1289
1290
1291
1292
1293
1294
1295
1296
1297

1298
1299
1300
1301
1302
1303
1304
950
951
952
953
954
955
956

957
958
959
960
961
962
963
964
965

966
967
968
969
970
971
972
973







-
+








-
+







    GC gc,			/* Use this GC. */
    int x, int y,		/* Upper left of bounding rect. */
    unsigned int width,		/* Width & height. */
    unsigned int height,
    int angle1,			/* Staring angle of arc. */
    int angle2)			/* Extent of arc. */
{
    MacDrawable *macWin = (MacDrawable *) d;
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    int lw = gc->line_width;

    if (width == 0 || height == 0 || angle2 == 0) {
	return BadDrawable;
    }

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0, u = 0;

	if (notAA(lw)) {
1357
1358
1359
1360
1361
1362
1363
1364

1365
1366
1367
1368
1369
1370

1371
1372
1373
1374
1375
1376
1377
1026
1027
1028
1029
1030
1031
1032

1033
1034
1035
1036
1037
1038

1039
1040
1041
1042
1043
1044
1045
1046







-
+





-
+







XFillArcs(
    Display *display,
    Drawable d,
    GC gc,
    XArc *arcArr,
    int nArcs)
{
    MacDrawable *macWin = (MacDrawable *) d;
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    XArc * arcPtr;
    int i, lw = gc->line_width;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0, u = 0;

	if (notAA(lw)) {
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
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
TkScrollWindow(
    Tk_Window tkwin,		/* The window to be scrolled. */
    GC gc,			/* GC for window to be scrolled. */
    TCL_UNUSED(GC),			/* GC for window to be scrolled. */
    int x, int y,		/* Position rectangle to be scrolled. */
    int width, int height,
    int dx, int dy,		/* Distance rectangle should be moved. */
    Region damageRgn)		/* Region to accumulate damage in. */
{
    Drawable drawable = Tk_WindowId(tkwin);
    MacDrawable *macDraw = (MacDrawable *) drawable;
    TKContentView *view = (TKContentView *) TkMacOSXDrawableView(macDraw);
    MacDrawable *macDraw = (MacDrawable *)drawable;
    TKContentView *view = (TKContentView *)TkMacOSXGetNSViewForDrawable(macDraw);
    CGRect srcRect, dstRect;
    HIShapeRef dmgRgn = NULL, extraRgn = NULL;
    NSRect bounds, visRect, scrollSrc, scrollDst;
    int result = 0;
    (void)gc;

    if (view) {
  	/*
	 * Get the scroll area in NSView coordinates (origin at bottom left).
	 */

  	bounds = [view bounds];
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
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







-
-
+
+

-
-
-









-
+


-
-
+
+



-
+
+
+








-


-
+

-
+

-
-


-
+
-



-
+
+
+
+
+



-
+
+










-
-
+
+




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





-
+
+
+
+
+
+
+
+

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

-
+


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

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

-
-
-
-
-
+
+
+
+
+

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

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

-
-
-
-
-
+
+
+

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

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




+










+







 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXSetUpGraphicsPort(
    GC gc,			/* GC to apply to current port. */
    void *destPort)
    TCL_UNUSED(GC),			/* GC to apply to current port. */
    TCL_UNUSED(void *))
{
    (void)gc;
    (void)destPort;

    Tcl_Panic("TkMacOSXSetUpGraphicsPort: Obsolete, no more QD!");
}


/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXSetUpDrawingContext --
 *
 *	Set up a drawing context for the given drawable and GC.
 *	Set up a drawing context for the given drawable from an X GC.
 *
 * Results:
 *	Boolean indicating whether it is ok to draw; if false, drawing context
 *	was not setup, so do not attempt to draw and do not call
 *	Boolean indicating whether it is ok to draw; if false, the drawing
 *	context was not setup, so do not attempt to draw and do not call
 *	TkMacOSXRestoreDrawingContext().
 *
 * Side effects:
 *	None.
 *	May modify or create the drawable's graphics context.  May expand the
 *      drawable's dirty rectangle.  When the result is true The dcPtr
 *      parameter is set to reference the new or updated drawing context.
 *
 *----------------------------------------------------------------------
 */

Bool
TkMacOSXSetupDrawingContext(
    Drawable d,
    GC gc,
    int useCG,			/* advisory only ! */
    TkMacOSXDrawingContext *dcPtr)
{
    MacDrawable *macDraw = (MacDrawable *) d;
    MacDrawable *macDraw = (MacDrawable *)d;
    Bool canDraw = true;
    NSWindow *win = NULL;
    TKContentView *view = nil;
    TkMacOSXDrawingContext dc = {};
    CGRect clipBounds;
    (void)useCG;

    /*
     * If the drawable is not a pixmap and it has an associated NSWindow then
     * If the drawable is not a pixmap, get the associated NSView.
     * we know we are drawing to a window.
     */

    if (!(macDraw->flags & TK_IS_PIXMAP)) {
	win = TkMacOSXDrawableWindow(d);
	view = (TKContentView *)TkMacOSXGetNSViewForDrawable(d);
	if (!view) {
	    Tcl_Panic("TkMacOSXSetupDrawingContext(): "
		    "no NSView to draw into !");
	}
    }

    /*
     * Check that we have a non-empty clipping region.
     * Intersect the drawable's clipping region with the region stored in the
     * X GC.  If the resulting region is empty, don't do any drawing.
     */

    dc.clipRgn = TkMacOSXGetClipRgn(d);
    ClipToGC(d, gc, &dc.clipRgn);
    if (dc.clipRgn && HIShapeIsEmpty(dc.clipRgn)) {
	canDraw = false;
	goto end;
    }

    /*
     * If we already have a CGContext, use it.  Otherwise, if we are drawing to
     * a window then we can get one from the window.
     * If the drawable already has a CGContext, use it.  Otherwise, we must be
     * drawing to a window and we use the current context of its ContentView.
     */

    dc.context = TkMacOSXGetCGContextForDrawable(d);
    if (dc.context) {
	dc.portBounds = clipBounds = CGContextGetClipBoundingBox(dc.context);
	dc.portBounds = CGContextGetClipBoundingBox(dc.context);
    } else if (win) {
	NSView *view = TkMacOSXDrawableView(macDraw);

	if (!view) {
	    Tcl_Panic("TkMacOSXSetupDrawingContext(): "
		    "no NSView to draw into !");
	}

	/*
	 * We can only draw into the view when the current CGContext is valid
	 * and belongs to the view.  Validity can only be guaranteed inside of
	 * a view's drawRect or setFrame methods.  The isDrawing attribute
	 * tells us whether we are being called from one of those methods.
	 *
	 * If the CGContext is not valid then we mark our view as needing
	 * display in the bounding rectangle of the clipping region and
	 * return failure.  That rectangle should get drawn in a later call
	 * to drawRect.
	 *
	 * As an exception to the above, if mouse buttons are pressed at the
	 * moment when we fail to obtain a valid context we schedule the entire
	 * view for a redraw rather than just the clipping region.  The purpose
	 * of this is to make sure that scrollbars get updated correctly.
	 */

	if (![NSApp isDrawing] || view != [NSView focusView]) {
	    NSRect bounds = [view bounds];
	    NSRect dirtyNS = bounds;
	    if ([NSEvent pressedMouseButtons]) {
		[view setNeedsDisplay:YES];
	    } else {
    } else {
		CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
					.ty = dirtyNS.size.height};
		if (dc.clipRgn) {
		    CGRect dirtyCG = NSRectToCGRect(dirtyNS);
		    HIShapeGetBounds(dc.clipRgn, &dirtyCG);
	NSRect drawingBounds, currentBounds;
		    dirtyNS = NSRectToCGRect(CGRectApplyAffineTransform(dirtyCG, t));
		}
		[view setNeedsDisplayInRect:dirtyNS];
	    }
	    canDraw = false;
	    goto end;
	}

	dc.view = view;
	dc.context = GET_CGCONTEXT;
	dc.portBounds = NSRectToCGRect([view bounds]);
	if (dc.clipRgn) {
	    clipBounds = CGContextGetClipBoundingBox(dc.context);
	    CGRect clipBounds;
	    CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
				    .ty = [view bounds].size.height};
	    HIShapeGetBounds(dc.clipRgn, &clipBounds);
	    clipBounds = CGRectApplyAffineTransform(clipBounds, t);
	    drawingBounds = NSRectFromCGRect(clipBounds);
	} else {
	    drawingBounds = [view bounds];
	}
    } else {
	Tcl_Panic("TkMacOSXSetupDrawingContext(): "
		"no context to draw into !");
    }


	/*
	 * We can only draw into the NSView which is the current focusView.
	 * When the current [NSView focusView] is nil, the CGContext for
	 * [NSGraphicsContext currentContext] is nil.  Otherwise the current
	 * CGContext draws into the current focusView.  An NSView is guaranteed
	 * to be the focusView when its drawRect or setFrame methods are
	 * running.  Prior to OSX 10.14 it was also possible to call the
	 * lockFocus method to force an NSView to become the current focusView.
	 * But that method was deprecated in 10.14 and so is no longer used by
	 * Tk.  Instead, if the view is not the current focusView then we add
	 * the drawing bounds to its dirty rectangle and return false.  The
	 * part of the view inside the drawing bounds will get redrawn during
	 * the next call to its drawRect method.
	 */

	if (view != [NSView focusView]) {
	    [view addTkDirtyRect:drawingBounds];
	    canDraw = false;
	    goto end;
	}

	/*
	 * Drawing will also fail when the view is the current focusView but
	 * the clipping rectangle set by drawRect does not contain the clipping
	 * region of our drawing context.  (See bug [2a61eca3a8].)  If part of
	 * the drawing bounds will be clipped then we draw whatever we can, but
	 * we also add the drawing bounds to the view's dirty rectangle so it
	 * will get redrawn in the next call to its drawRect method.
	 */

	currentBounds = NSRectFromCGRect(CGContextGetClipBoundingBox(dc.context));
	if (!NSContainsRect(currentBounds, drawingBounds)) {
	    [view addTkDirtyRect:drawingBounds];
	}
    }

    /*
     * Configure the drawing context.
     * Finish configuring the drawing context.
     */

    if (dc.context) {
	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 = dc.portBounds.size.height
    };

	dc.portBounds.origin.x += macDraw->xOff;
	dc.portBounds.origin.y += macDraw->yOff;
	CGContextSaveGState(dc.context);
	CGContextSetTextDrawingMode(dc.context, kCGTextFill);
	CGContextConcatCTM(dc.context, t);
	if (dc.clipRgn) {
    dc.portBounds.origin.x += macDraw->xOff;
    dc.portBounds.origin.y += macDraw->yOff;
    CGContextSaveGState(dc.context);
    CGContextSetTextDrawingMode(dc.context, kCGTextFill);
    CGContextConcatCTM(dc.context, t);
    if (dc.clipRgn) {

#ifdef TK_MAC_DEBUG_DRAWING
	    CGContextSaveGState(dc.context);
	    ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);
	    CGContextSetRGBFillColor(dc.context, 1.0, 0.0, 0.0, 0.1);
	    CGContextEOFillPath(dc.context);
	    CGContextRestoreGState(dc.context);
	CGContextSaveGState(dc.context);
	ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);
	CGContextSetRGBFillColor(dc.context, 1.0, 0.0, 0.0, 0.1);
	CGContextEOFillPath(dc.context);
	CGContextRestoreGState(dc.context);
#endif /* TK_MAC_DEBUG_DRAWING */

	    CGRect r;

	    if (!HIShapeIsRectangular(dc.clipRgn) || !CGRectContainsRect(
		    *HIShapeGetBounds(dc.clipRgn, &r),
	CGRect r;
	CGRect b = CGRectApplyAffineTransform(
	    CGContextGetClipBoundingBox(dc.context), t);
	if (!HIShapeIsRectangular(dc.clipRgn) ||
	    !CGRectContainsRect(*HIShapeGetBounds(dc.clipRgn, &r), b)) {
		    CGRectApplyAffineTransform(clipBounds, t))) {
		ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);
		CGContextEOClip(dc.context);
	    }
	}
	if (gc) {
	    static const CGLineCap cgCap[] = {
		[CapNotLast] = kCGLineCapButt,
		[CapButt] = kCGLineCapButt,
		[CapRound] = kCGLineCapRound,
		[CapProjecting] = kCGLineCapSquare,
	    };
	    static const CGLineJoin cgJoin[] = {
		[JoinMiter] = kCGLineJoinMiter,
		[JoinRound] = kCGLineJoinRound,
		[JoinBevel] = kCGLineJoinBevel,
	    };
	    bool shouldAntialias;
	    double w = gc->line_width;
	    ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);
	    CGContextEOClip(dc.context);
	}
    }
    if (gc) {
	static const CGLineCap cgCap[] = {
	    [CapNotLast] = kCGLineCapButt,
	    [CapButt] = kCGLineCapButt,
	    [CapRound] = kCGLineCapRound,
	    [CapProjecting] = kCGLineCapSquare,
	};
	static const CGLineJoin cgJoin[] = {
	    [JoinMiter] = kCGLineJoinMiter,
	    [JoinRound] = kCGLineJoinRound,
	    [JoinBevel] = kCGLineJoinBevel,
	};
	bool shouldAntialias = !notAA(gc->line_width);
	double w = gc->line_width;

	    TkMacOSXSetColorInContext(gc, gc->foreground, dc.context);
	    if (win) {
		CGContextSetPatternPhase(dc.context, CGSizeMake(
			dc.portBounds.size.width, dc.portBounds.size.height));
	    }
	    if (gc->function != GXcopy) {
		TkMacOSXDbgMsg("Logical functions other than GXcopy are "
			"not supported for CG drawing!");
	    }

	TkMacOSXSetColorInContext(gc, gc->foreground, dc.context);
	if (view) {
	    CGContextSetPatternPhase(dc.context, CGSizeMake(
	        dc.portBounds.size.width, dc.portBounds.size.height));
	}
	if (gc->function != GXcopy) {
	    TkMacOSXDbgMsg("Logical functions other than GXcopy are "
			   "not supported for CG drawing!");
	}
	if (!shouldAntialias) {
	    /*
	     * When should we antialias?
	     */

	    shouldAntialias = !notAA(gc->line_width);
	    if (!shouldAntialias) {
		/*
		 * Make non-antialiased CG drawing look more like X11.
		 */
	    /*
	     * Make non-antialiased CG drawing look more like X11.
	     */

		w -= (gc->line_width ? NON_AA_CG_OFFSET : 0);
	    }
	    CGContextSetShouldAntialias(dc.context, shouldAntialias);
	    CGContextSetLineWidth(dc.context, w);
	    if (gc->line_style != LineSolid) {
		int num = 0;
		char *p = &gc->dashes;
		CGFloat dashOffset = gc->dash_offset;
		CGFloat lengths[10];
	    w -= (gc->line_width ? NON_AA_CG_OFFSET : 0);
	}
	CGContextSetShouldAntialias(dc.context, shouldAntialias);
	CGContextSetLineWidth(dc.context, w);
	if (gc->line_style != LineSolid) {
	    int num = 0;
	    char *p = &gc->dashes;
	    CGFloat dashOffset = gc->dash_offset;
	    dashOffset -= (gc->line_width % 2) ? 0.5 : 0.0;
	    CGFloat lengths[10];

		while (p[num] != '\0' && num < 10) {
		    lengths[num] = p[num];
		    num++;
		}
		CGContextSetLineDash(dc.context, dashOffset, lengths, num);
	    }
	    if ((unsigned) gc->cap_style < sizeof(cgCap)/sizeof(CGLineCap)) {
		CGContextSetLineCap(dc.context,
	    while (p[num] != '\0' && num < 10) {
		lengths[num] = p[num];
		num++;
	    }
	    CGContextSetLineDash(dc.context, dashOffset, lengths, num);
	}
	if ((unsigned) gc->cap_style < sizeof(cgCap)/sizeof(CGLineCap)) {
	    CGContextSetLineCap(dc.context, cgCap[(unsigned) gc->cap_style]);
			cgCap[(unsigned) gc->cap_style]);
	    }
	    if ((unsigned)gc->join_style < sizeof(cgJoin)/sizeof(CGLineJoin)) {
		CGContextSetLineJoin(dc.context,
	}
	if ((unsigned)gc->join_style < sizeof(cgJoin)/sizeof(CGLineJoin)) {
	    CGContextSetLineJoin(dc.context, cgJoin[(unsigned) gc->join_style]);
			cgJoin[(unsigned) gc->join_style]);
	    }
	}
    }

end:

#ifdef TK_MAC_DEBUG_DRAWING
    if (!canDraw && win != NULL) {
	TkWindow *winPtr = TkMacOSXGetTkWindow(win);

	if (winPtr) {
	    fprintf(stderr, "Cannot draw in %s - postponing.\n",
		    Tk_PathName(winPtr));
	}
    }
#endif

    if (!canDraw && dc.clipRgn) {
	CFRelease(dc.clipRgn);
	dc.clipRgn = NULL;
    }
    *dcPtr = dc;
    return canDraw;
}
1826
1827
1828
1829
1830
1831
1832
1833

1834
1835
1836
1837
1838
1839
1840
1841

1842
1843
1844
1845
1846
1847
1848
1488
1489
1490
1491
1492
1493
1494

1495
1496
1497
1498
1499
1500
1501
1502

1503
1504
1505
1506
1507
1508
1509
1510







-
+







-
+







 *----------------------------------------------------------------------
 */

HIShapeRef
TkMacOSXGetClipRgn(
    Drawable drawable)		/* Drawable. */
{
    MacDrawable *macDraw = (MacDrawable *) drawable;
    MacDrawable *macDraw = (MacDrawable *)drawable;
    HIShapeRef clipRgn = NULL;

    if (macDraw->winPtr && macDraw->flags & TK_CLIP_INVALID) {
	TkMacOSXUpdateClipRgn(macDraw->winPtr);
#ifdef TK_MAC_DEBUG_DRAWING
	TkMacOSXDbgMsg("%s", macDraw->winPtr->pathName);

	NSView *view = TkMacOSXDrawableView(macDraw);
	NSView *view = TkMacOSXGetNSViewForDrawable(macDraw);
	CGContextRef context = GET_CGCONTEXT;

	CGContextSaveGState(context);
	CGContextConcatCTM(context, CGAffineTransformMake(1.0, 0.0, 0.0,
	      -1.0, 0.0, [view bounds].size.height));
	ChkErr(HIShapeReplacePathInCGContext, macDraw->visRgn, context);
	CGContextSetRGBFillColor(context, 0.0, 1.0, 0.0, 0.1);
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
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







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
















-
+




-
+
-







    }
    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. */
{
    (void)drawable;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpClipDrawableToRect --
 *
 *	Clip all drawing into the drawable d to the given rectangle. If width
 *	or height are negative, reset to no clipping.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Subsequent drawing into d is offset and clipped as specified.
 *
 *----------------------------------------------------------------------
 */

void
TkpClipDrawableToRect(
    Display *display,
    TCL_UNUSED(Display *),
    Drawable d,
    int x, int y,
    int width, int height)
{
    MacDrawable *macDraw = (MacDrawable *) d;
    MacDrawable *macDraw = (MacDrawable *)d;
    (void)display;

    if (macDraw->drawRgn) {
	CFRelease(macDraw->drawRgn);
	macDraw->drawRgn = NULL;
    }
    if (width >= 0 && height >= 0) {
	CGRect clipRect = CGRectMake(x + macDraw->xOff, y + macDraw->yOff,
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961




1962
1963
1964
1965
1966
1967
1968
1588
1589
1590
1591
1592
1593
1594




1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605







-
-
-
-
+
+
+
+







static void
ClipToGC(
    Drawable d,
    GC gc,
    HIShapeRef *clipRgnPtr) /* must point to initialized variable */
{
    if (gc && gc->clip_mask &&
	    ((TkpClipMask *) gc->clip_mask)->type == TKP_CLIP_REGION) {
	Region gcClip = ((TkpClipMask *) gc->clip_mask)->value.region;
	int xOffset = ((MacDrawable *) d)->xOff + gc->clip_x_origin;
	int yOffset = ((MacDrawable *) d)->yOff + gc->clip_y_origin;
	    ((TkpClipMask *)gc->clip_mask)->type == TKP_CLIP_REGION) {
	Region gcClip = ((TkpClipMask *)gc->clip_mask)->value.region;
	int xOffset = ((MacDrawable *)d)->xOff + gc->clip_x_origin;
	int yOffset = ((MacDrawable *)d)->yOff + gc->clip_y_origin;
	HIShapeRef clipRgn = *clipRgnPtr, gcClipRgn;

	XOffsetRegion(gcClip, xOffset, yOffset);
	gcClipRgn = TkMacOSXGetNativeRegion(gcClip);
	if (clipRgn) {
	    *clipRgnPtr = HIShapeCreateIntersection(gcClipRgn, clipRgn);
	    CFRelease(clipRgn);
1990
1991
1992
1993
1994
1995
1996
1997
1998


1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
1627
1628
1629
1630
1631
1632
1633


1634
1635
1636



1637
1638
1639
1640
1641
1642
1643







-
-
+
+

-
-
-







 *	None.
 *
 *----------------------------------------------------------------------
 */

void *
TkMacOSXMakeStippleMap(
    Drawable drawable,		/* Window to apply stipple. */
    Drawable stipple)		/* The stipple pattern. */
    TCL_UNUSED(Drawable),	/* Window to apply stipple. */
    TCL_UNUSED(Drawable))	/* The stipple pattern. */
{
    (void)drawable;
    (void)stipple;

    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawHighlightBorder --

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 <[email protected]>
 * Copyright © 1996-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2006-2009 Daniel A. Steffen <[email protected]>
 *
 * 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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
39
40
41
42
43
44
45





46
47
48
49
50
51
52
53
54
55
56
57
58
59




































60
61
62
63
64
65
66







-
-
-
-
-














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







    struct Container *nextPtr;	/* Next in list of all containers in this
				 * process. */
} Container;

static Container *firstContainerPtr = NULL;
				/* First in list of all containers managed by
				 * this process. */
/*
 * Globals defined in this file:
 */

TkMacOSXEmbedHandler *tkMacOSXEmbedHandler = NULL;

/*
 * Prototypes for static procedures defined in this file:
 */

static void	ContainerEventProc(ClientData clientData, XEvent *eventPtr);
static void	EmbeddedEventProc(ClientData clientData, XEvent *eventPtr);
static void	EmbedActivateProc(ClientData clientData, XEvent *eventPtr);
static void	EmbedFocusProc(ClientData clientData, XEvent *eventPtr);
static void	EmbedGeometryRequest(Container *containerPtr, int width,
		    int height);
static void	EmbedSendConfigure(Container *containerPtr);
static void	EmbedStructureProc(ClientData clientData, XEvent *eventPtr);
static void	EmbedWindowDeleted(TkWindow *winPtr);

/*
 *----------------------------------------------------------------------
 *
 * Tk_MacOSXSetEmbedHandler --
 *
 *	Registers a handler for an in process form of embedding, like Netscape
 *	plugins, where Tk is loaded into the process, but does not control the
 *	main window
 *
 * Results:
 *	None
 *
 * Side effects:
 *	The embed handler is set.
 *
 *----------------------------------------------------------------------
 */

void
Tk_MacOSXSetEmbedHandler(
    Tk_MacOSXEmbedRegisterWinProc *registerWinProc,
    Tk_MacOSXEmbedGetGrafPortProc *getPortProc,
    Tk_MacOSXEmbedMakeContainerExistProc *containerExistProc,
    Tk_MacOSXEmbedGetClipProc *getClipProc,
    Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc)
{
    if (tkMacOSXEmbedHandler == NULL) {
	tkMacOSXEmbedHandler = (TkMacOSXEmbedHandler *)ckalloc(sizeof(TkMacOSXEmbedHandler));
    }
    tkMacOSXEmbedHandler->registerWinProc = registerWinProc;
    tkMacOSXEmbedHandler->getPortProc = getPortProc;
    tkMacOSXEmbedHandler->containerExistProc = containerExistProc;
    tkMacOSXEmbedHandler->getClipProc = getClipProc;
    tkMacOSXEmbedHandler->getOffsetProc = getOffsetProc;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpMakeWindow --
 *
 *	Creates an X Window (Mac subwindow).
443
444
445
446
447
448
449
450

451
452
453
454
455
456
457
402
403
404
405
406
407
408

409
410
411
412
413
414
415
416







-
+







    TkWindow *winPtr)		/* Tk's structure for an embedded window. */
{
    Container *containerPtr;

    for (containerPtr = firstContainerPtr; containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
	if (containerPtr->embeddedPtr == winPtr) {
	    return (MacDrawable *) containerPtr->parent;
	    return (MacDrawable *)containerPtr->parent;
	}
    }
    Tcl_Panic("TkMacOSXContainerId couldn't find window");
    return NULL;
}

/*
855
856
857
858
859
860
861
862

863
864
865
866
867
868
869
814
815
816
817
818
819
820

821
822
823
824
825
826
827
828







-
+







    } else if (eventPtr->type == DestroyNotify) {
	/*
	 * It is not clear whether the container should be destroyed
	 * when an embedded window is destroyed.  See ticket [67384bce7d].
	 * Here we are following unix, by destroying the container.
	 */

	Tk_DestroyWindow((Tk_Window) winPtr);
	Tk_DestroyWindow((Tk_Window)winPtr);
    }
    Tk_DeleteErrorHandler(errHandler);
}

/*
 *----------------------------------------------------------------------
 *
904
905
906
907
908
909
910
911
912


913
914
915
916
917
918
919
863
864
865
866
867
868
869


870
871
872
873
874
875
876
877
878







-
-
+
+







	    /*
	     * Ignore errors, since the embedded application could have
	     * deleted its window.
	     */

	    errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1,
		    -1, -1, NULL, NULL);
	    Tk_MoveResizeWindow((Tk_Window) containerPtr->embeddedPtr, 0, 0,
		    (unsigned) Tk_Width((Tk_Window) containerPtr->parentPtr),
	    Tk_MoveResizeWindow((Tk_Window)containerPtr->embeddedPtr, 0, 0,
		    (unsigned) Tk_Width((Tk_Window)containerPtr->parentPtr),
		    (unsigned) Tk_Height((Tk_Window)containerPtr->parentPtr));
	    Tk_DeleteErrorHandler(errHandler);
	}
    } else if (eventPtr->type == DestroyNotify) {
	EmbedWindowDeleted(containerPtr->parentPtr);
    }
}
1050
1051
1052
1053
1054
1055
1056
1057
1058


1059
1060
1061
1062
1063
1064
1065
1066
1067
1009
1010
1011
1012
1013
1014
1015


1016
1017


1018
1019
1020
1021
1022
1023
1024







-
-
+
+
-
-







     * the container window. We need to send a Configure event back to the
     * embedded application if we decide not to honor its request; to make this
     * happen, process all idle event handlers synchronously here (so that the
     * geometry managers have had a chance to do whatever they want to do), and
     * if the window's size didn't change then generate a configure event.
     */

    Tk_GeometryRequest((Tk_Window) winPtr, width, height);
    while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {
    Tk_GeometryRequest((Tk_Window)winPtr, width, height);
    while (Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_TIMER_EVENTS|TCL_DONT_WAIT)) {}
	/* Empty loop body. */
    }
    if ((winPtr->changes.width != width)
	    || (winPtr->changes.height != height)) {
	EmbedSendConfigure(containerPtr);
    }
}

/*

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 <[email protected]>
 * Copyright 2008-2009, Apple Inc.
 * Copyright © 2001 Apple Computer, Inc.
 * Copyright © 2006-2009 Daniel A. Steffen <[email protected]>
 * 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"
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







-
+







    int isSpinbox)
{
    CGRect bounds;
    TkMacOSXDrawingContext dc;
    GC bgGC;
    Tk_Window tkwin = entryPtr->tkwin;
    int oldWidth = 0;
    MacDrawable *macDraw = (MacDrawable *) d;
    MacDrawable *macDraw = (MacDrawable *)d;
    const HIThemeFrameDrawInfo info = {
	.version = 0,
	.kind = kHIThemeFrameTextFieldSquare,
	.state = (entryPtr->state == STATE_DISABLED ? kThemeStateInactive :
		kThemeStateActive),
	.isFocused = (entryPtr->flags & GOT_FOCUS ? 1 : 0),
    };
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







-
+







     * 3 according to the Carbon docs.
     */

    bounds.origin.x = macDraw->xOff + MAC_OSX_FOCUS_WIDTH;
    bounds.origin.y = macDraw->yOff + MAC_OSX_FOCUS_WIDTH;
    bounds.size.width = Tk_Width(tkwin) - 2*MAC_OSX_FOCUS_WIDTH;
    bounds.size.height = Tk_Height(tkwin) - 2*MAC_OSX_FOCUS_WIDTH;
    if (!TkMacOSXSetupDrawingContext(d, NULL, 1, &dc)) {
    if (!TkMacOSXSetupDrawingContext(d, NULL, &dc)) {

	/*
	 * No graphics context is available.  If the widget is a Spinbox, we
	 * must restore its width before returning 0. (Ticket [273b6a4996].)
	 */

	if (isSpinbox) {
204
205
206
207
208
209
210
211

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

211
212
213
214
215
216
217
218







-
+







    Tk_Window tkwin = sbPtr->entry.tkwin;
    int height = Tk_Height(tkwin);
    int buttonHeight = height - 2 * MAC_OSX_FOCUS_WIDTH;
    int incDecWidth;
    TkMacOSXDrawingContext dc;
    XRectangle rects[1];
    GC bgGC;
    MacDrawable *macDraw = (MacDrawable *) d;
    MacDrawable *macDraw = (MacDrawable *)d;
    HIThemeButtonDrawInfo info = {
	.version = 0,
	.adornment = kThemeAdornmentNone,
    };

    /*
     * FIXME: RAISED really makes more sense
261
262
263
264
265
266
267
268

269
270
271
272
273
274
275
261
262
263
264
265
266
267

268
269
270
271
272
273
274
275







-
+







    bgGC = Tk_GCForColor(sbPtr->entry.highlightBgColorPtr, d);
    rects[0].x = Tk_Width(tkwin) - incDecWidth - 1;
    rects[0].y = 0;
    rects[0].width = incDecWidth + 1;
    rects[0].height = Tk_Height(tkwin);
    XFillRectangles(Tk_Display(tkwin), d, bgGC, rects, 1);

    if (!TkMacOSXSetupDrawingContext(d, NULL, 1, &dc)) {
    if (!TkMacOSXSetupDrawingContext(d, NULL, &dc)) {
	return 0;
    }
    ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation, NULL);
    TkMacOSXRestoreDrawingContext(&dc);
    return 1;
}


Changes to macosx/tkMacOSXEvent.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





-
-
-
+
+
+







/*
 * 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 <[email protected]>
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009, Apple Inc.
 * Copyright © 2005-2009 Daniel A. Steffen <[email protected]>
 *
 * 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"
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

135
136
137
138
139
140











141
142

143
144

145
146
147

148
149
150
151
152
153
154
155
156
157
100
101
102
103
104
105
106

107






















108
109
110

111
112





113
114
115
116
117
118
119
120
121
122
123


124


125



126
127
128
129
130
131
132
133
134
135
136







-

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



-
+

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











    default:
	break; /* return theEvent */
    }
    return processedEvent;
}
@end

#pragma mark -

/*
 *----------------------------------------------------------------------
 *
 * XSync --
 *
 *	This routine is a stub called XSync, which is called during the Tk
 *      update command.  The language specification does not require that the
 *      update command be synchronous but many of the tests implicitly assume
 *      that it is.  It is definitely asynchronous on macOS since many idle
 *      tasks are run inside of the drawRect method of a window's contentView,
 *      which will not be called until after this function returns.
 *
 * Results:
 *	None.
 *
 * Side effects: Processes all pending idle events then calls the display
 *	method of each visible window.
 *
 *----------------------------------------------------------------------
 */

int
XSync(
    Display *display,
    Bool discard)
    TCL_UNUSED(Bool))
{
    (void)discard;

    if (display) {
	display->request++;
    }
    /*
     *  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.
     */

    if (Tk_GetNumMainWindows() != 0) {
	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)){}
    while (Tcl_DoOneEvent(TCL_TIMER_EVENTS|TCL_DONT_WAIT)){}
	for (NSWindow *w in [NSApp orderedWindows]) {
	    [w display];
    display->request++;
	}
    }
    return Success;
    return 0;
}

/*
 * 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, [email protected]
 * Copyright (c) 2006-2009 Daniel A. Steffen <[email protected]>
 * Copyright 2008-2009, Apple Inc.
 * Copyright © 2002-2004 Benjamin Riefenstahl, [email protected]
 * Copyright © 2006-2009 Daniel A. Steffen <[email protected]>
 * 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"
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
89
90
91
92
93
94
95




96
97
98
99
100
101
102







-
-
-
-







			    CGFloat size, int fallbackToDefault);
static void		InitFont(NSFont *nsFont,
			    const TkFontAttributes *reqFaPtr,
			    MacFont *fontPtr);
static int		CreateNamedSystemFont(Tcl_Interp *interp,
			    Tk_Window tkwin, const char *name,
			    TkFontAttributes *faPtr);
static void		DrawCharsInContext(Display *display, Drawable drawable,
			    GC gc, Tk_Font tkfont, const char *source,
			    int numBytes, int rangeStart, int rangeLength,
			    int x, int y, double angle);

#pragma mark -
#pragma mark Font Helpers:

/*
 * To avoid an extra copy, a TKNSString object wraps a Tcl_DString with an
 * NSString that uses the DString's buffer as its character buffer.  It can be
127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137







-
+







}

- (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);
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
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.
177
178
179
180
181
182
183

184
185
186
187
188
189
190
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183







+







	Tcl_DStringSetLength(&_ds, p - Tcl_DStringValue(&_ds));
    }
    return _ds;
}

#ifndef __clang__
@synthesize UTF8String = _UTF8String;
@synthesize DString = _ds;
#endif
@end

#define GetNSFontTraitsFromTkFontAttributes(faPtr) \
	((faPtr)->weight == TK_FW_BOLD ? NSBoldFontMask : NSUnboldFontMask) | \
	((faPtr)->slant == TK_FS_ITALIC ? NSItalicFontMask : NSUnitalicFontMask)

451
452
453
454
455
456
457
458

459
460
461
462
463
464
465
444
445
446
447
448
449
450

451
452
453
454
455
456
457
458







-
+







 */

void
TkpFontPkgInit(
    TkMainInfo *mainPtr)	/* The application being created. */
{
    Tcl_Interp *interp = mainPtr->interp;
    Tk_Window tkwin = (Tk_Window) mainPtr->winPtr;
    Tk_Window tkwin = (Tk_Window)mainPtr->winPtr;
    const struct SystemFontMapEntry *systemFont = systemFontMap;
    NSFont *nsFont;
    TkFontAttributes fa;
    NSMutableCharacterSet *cs;
    /*
     * Since we called before TkpInit, we need our own autorelease pool.
     */
550
551
552
553
554
555
556
557

558
559
560
561
562
563
564
565
566
567
568
569
570
543
544
545
546
547
548
549

550
551
552
553
554
555

556
557
558
559
560
561
562







-
+





-







 *	None.
 *
 *---------------------------------------------------------------------------
 */

TkFont *
TkpGetNativeFont(
    Tk_Window tkwin,		/* For display where font will be used. */
    TCL_UNUSED(Tk_Window),		/* For display where font will be used. */
    const char *name)		/* Platform-specific font name. */
{
    MacFont *fontPtr = NULL;
    ThemeFontID themeFontId;
    CTFontRef ctFont;
    (void)tkwin;

    if (strcmp(name, SYSTEMFONT_NAME) == 0) {
	themeFontId = kThemeSystemFont;
    } else if (strcmp(name, APPLFONT_NAME) == 0) {
	themeFontId = kThemeApplicationFont;
    } else if (strcmp(name, MENUITEMFONT_NAME) == 0) {
	themeFontId = kThemeMenuItemFont;
700
701
702
703
704
705
706
707

708
709
710
711
712
713
714
715
716
717
718
692
693
694
695
696
697
698

699
700
701
702

703
704
705
706
707
708
709







-
+



-







 *
 *---------------------------------------------------------------------------
 */

void
TkpGetFontFamilies(
    Tcl_Interp *interp,		/* Interp to hold result. */
    Tk_Window tkwin)		/* For display to query. */
    TCL_UNUSED(Tk_Window))		/* For display to query. */
{
    Tcl_Obj *resultPtr = Tcl_NewListObj(0, NULL);
    NSArray *list = [[NSFontManager sharedFontManager] availableFontFamilies];
    (void)tkwin;

    for (NSString *family in list) {
	Tcl_ListObjAppendElement(NULL, resultPtr,
		Tcl_NewStringObj([family UTF8String], -1));
    }
    Tcl_SetObjResult(interp, resultPtr);
}
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
765
766
767
768
769
770
771

772
773
774
775
776
777
778
779
780
781

782
783
784
785
786
787
788







-
+









-







 *	The font attributes are stored in *faPtr.
 *
 *----------------------------------------------------------------------
 */

void
TkpGetFontAttrsForChar(
    Tk_Window tkwin,		/* Window on the font's display */
    TCL_UNUSED(Tk_Window),		/* Window on the font's display */
    Tk_Font tkfont,		/* Font to query */
    int c,         		/* Character of interest */
    TkFontAttributes* faPtr)	/* Output: Font attributes */
{
    MacFont *fontPtr = (MacFont *) tkfont;
    NSFont *nsFont = fontPtr->nsFont;
    *faPtr = fontPtr->font.fa;
    if (nsFont && ![[nsFont coveredCharacterSet] characterIsMember:c]) {
	UTF16Char ch = (UTF16Char) c;
    (void)tkwin;

	nsFont = [nsFont bestMatchingFontForCharacters:&ch
		length:1 attributes:nil actualCoveredLength:NULL];
	if (nsFont) {
	    GetTkFontAttributesForNSFont(nsFont, faPtr);
	}
    }
1062
1063
1064
1065
1066
1067
1068
1069

1070
1071
1072
1073
1074
1075
1076
1052
1053
1054
1055
1056
1057
1058

1059
1060
1061
1062
1063
1064
1065
1066







-
+







 *---------------------------------------------------------------------------
 *
 * Tk_DrawChars --
 *
 *	Draw a string of characters on the screen.
 *
 *	With ATSUI we need the line context to do this right, so we have the
 *	actual implementation in TkpDrawCharsInContext().
 *	actual implementation in TkpDrawAngledCharsInContext().
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Information gets drawn on the screen.
 *
1091
1092
1093
1094
1095
1096
1097
1098

1099
1100
1101
1102
1103
1104
1105
1081
1082
1083
1084
1085
1086
1087

1088
1089
1090
1091
1092
1093
1094
1095







-
+







				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int x, int y)		/* Coordinates at which to place origin of the
				 * string when drawing. */
{
    DrawCharsInContext(display, drawable, gc, tkfont, source, numBytes,
    TkpDrawAngledCharsInContext(display, drawable, gc, tkfont, source, numBytes,
	    0, numBytes, x, y, 0.0);
}

void
TkDrawAngledChars(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
1114
1115
1116
1117
1118
1119
1120
1121

1122
1123
1124
1125
1126
1127
1128
1104
1105
1106
1107
1108
1109
1110

1111
1112
1113
1114
1115
1116
1117
1118







-
+







				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    double x, double y,		/* Coordinates at which to place origin of
				 * string when drawing. */
    double angle)		/* What angle to put text at, in degrees. */
{
    DrawCharsInContext(display, drawable, gc, tkfont, source, numBytes,
    TkpDrawAngledCharsInContext(display, drawable, gc, tkfont, source, numBytes,
	    0, numBytes, x, y, angle);
}

/*
 *---------------------------------------------------------------------------
 *
 * TkpDrawCharsInContext --
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
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







-
+



-
-
-
+
+
+














-
+


-
+








-
+






-



-
+








-
+


-

-
+
-







    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;
    DrawCharsInContext(display, drawable, gc, tkfont, source, numBytes,
    TkpDrawAngledCharsInContext(display, drawable, gc, tkfont, source, numBytes,
	    rangeStart, rangeLength, x, y, 0.0);
}

static void
DrawCharsInContext(
    Display *display,		/* Display on which to draw. */
void
TkpDrawAngledCharsInContext(
    TCL_UNUSED(Display *),		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn; must
				 * be the same as font used in GC. */
    const char * source,	/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that is
				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int rangeStart,		/* Index of first byte to draw. */
    int rangeLength,		/* Length of range to draw in bytes. */
    int x, int y,		/* Coordinates at which to place origin of the
    double x, double y,		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
    double angle)
    double angle)		/* What angle to put text at, in degrees. */
{
    const MacFont *fontPtr = (const MacFont *) tkfont;
    NSString *string;
    NSMutableDictionary *attributes;
    NSAttributedString *attributedString;
    CTTypesetterRef typesetter;
    CFIndex start, length;
    CTLineRef line, full=nil;
    MacDrawable *macWin = (MacDrawable *) drawable;
    MacDrawable *macWin = (MacDrawable *)drawable;
    TkMacOSXDrawingContext drawingContext;
    CGContextRef context;
    CGColorRef fg;
    NSFont *nsFont;
    CGAffineTransform t;
    CGFloat width, height, textX = (CGFloat) x, textY = (CGFloat) y;
    (void)display;

    if (rangeStart < 0 || rangeLength <= 0  ||
	rangeStart + rangeLength > numBytes ||
	!TkMacOSXSetupDrawingContext(drawable, gc, 1, &drawingContext)) {
	!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];
    [attributes setObject:(id)fg forKey:(id)kCTForegroundColorAttributeName];
    CFRelease(fg);
    nsFont = [attributes objectForKey:NSFontAttributeName];
    [nsFont setInContext:[NSGraphicsContext graphicsContextWithGraphicsPort:
    [nsFont setInContext:GET_NSCONTEXT(context, NO)];
	    context flipped:NO]];
    CGContextSetTextMatrix(context, CGAffineTransformIdentity);
    attributedString = [[NSAttributedString alloc] initWithString:string
	    attributes:attributes];
    typesetter = CTTypesetterCreateWithAttributedString(
	    (CFAttributedStringRef)attributedString);
    textX += (CGFloat) macWin->xOff;
    textY += (CGFloat) macWin->yOff;
1332
1333
1334
1335
1336
1337
1338
1339
1340


1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1319
1320
1321
1322
1323
1324
1325


1326
1327
1328



1329
1330
1331
1332
1333
1334
1335







-
-
+
+

-
-
-







 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkMacOSXIsCharacterMissing(
    Tk_Font tkfont,		/* The font we are looking in. */
    unsigned int searchChar)	/* The character we are looking for. */
    TCL_UNUSED(Tk_Font),		/* The font we are looking in. */
    TCL_UNUSED(unsigned int))	/* The character we are looking for. */
{
    (void)tkfont;
    (void)searchChar;

    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXFontDescriptionForNSFontAndNSFontAttributes --
1376
1377
1378
1379
1380
1381
1382
1383

1384
1385
1386
1387
1388
1389
1390
1360
1361
1362
1363
1364
1365
1366

1367
1368
1369
1370
1371
1372
1373
1374







-
+







	id underline = [nsAttributes objectForKey:
		NSUnderlineStyleAttributeName];
	id strikethrough = [nsAttributes objectForKey:
		NSStrikethroughStyleAttributeName];

	objv[i++] = Tcl_NewStringObj(familyName, -1);
	objv[i++] = Tcl_NewWideIntObj([nsFont pointSize]);
#define S(s)    Tcl_NewStringObj(STRINGIFY(s), (int)(sizeof(STRINGIFY(s))-1))
#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 <[email protected]>
 * 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 <[email protected]>
 *
 * 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 <[email protected]>
 * 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 <[email protected]>
 * 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>
35
36
37
38
39
40
41

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





61
62
63
64
65
66
67
68
69






70
71
72
73
74
75
76
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56





57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83







+














-
-
-
-
-
+
+
+
+
+









+
+
+
+
+
+







 */

typedef struct AppleEventInfo {
    Tcl_Interp *interp;
    const char *procedure;
    Tcl_DString command;
    NSAppleEventDescriptor *replyEvent; /* Only used for DoScriptText. */
    int retryCount;
} AppleEventInfo;

/*
 * Static functions used only in this file.
 */

static int  MissedAnyParameters(const AppleEvent *theEvent);
static int  ReallyKillMe(Tcl_Event *eventPtr, int flags);
static void ProcessAppleEvent(ClientData clientData);

/*
 * Names of the procedures which can be used to process AppleEvents.
 */

static const char* openDocumentProc = "::tk::mac::OpenDocument";
static const char* launchURLProc = "::tk::mac::LaunchURL";
static const char* printDocProc = "::tk::mac::PrintDocument";
static const char* scriptFileProc = "::tk::mac::DoScriptFile";
static const char* scriptTextProc = "::tk::mac::DoScriptText";
static const char openDocumentProc[] = "::tk::mac::OpenDocument";
static const char launchURLProc[] = "::tk::mac::LaunchURL";
static const char printDocProc[] = "::tk::mac::PrintDocument";
static const char scriptFileProc[] = "::tk::mac::DoScriptFile";
static const char scriptTextProc[] = "::tk::mac::DoScriptText";

#pragma mark TKApplication(TKHLEvents)

@implementation TKApplication(TKHLEvents)
- (void) terminate: (id) sender
{
    (void)sender;
    [self handleQuitApplicationEvent:Nil withReplyEvent:Nil];
}

- (void) superTerminate: (id) sender
{
    (void) sender;
    [super terminate:nil];
}

- (void) preferences: (id) sender
{
    (void)sender;
    [self handleShowPreferencesEvent:Nil withReplyEvent:Nil];
}

226
227
228
229
230
231
232







233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251


252
253
254
255
256
257
258
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274







+
+
+
+
+
+
+



















+
+








    Tcl_FreeEncoding(utf8);
    AEDisposeDesc(&contents);
    AEInfo->interp = _eventInterp;
    AEInfo->procedure = openDocumentProc;
    AEInfo->replyEvent = nil;
    Tcl_DoWhenIdle(ProcessAppleEvent, (ClientData)AEInfo);
    AEInfo->retryCount = 0;

    if (Tcl_FindCommand(_eventInterp, "::tk::mac::OpenDocuments", NULL, 0)){
	ProcessAppleEvent((ClientData)AEInfo);
    } else {
	Tcl_CreateTimerHandler(500, ProcessAppleEvent, (ClientData)AEInfo);
    }
}

- (void) handlePrintDocumentsEvent: (NSAppleEventDescriptor *)event
		    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
    NSString* file = [[event paramDescriptorForKeyword:keyDirectObject]
			 stringValue];
    const char *printFile = [file UTF8String];
    AppleEventInfo *AEInfo = (AppleEventInfo *)ckalloc(sizeof(AppleEventInfo));
    Tcl_DString *printCommand = &AEInfo->command;
    (void)replyEvent;

    Tcl_DStringInit(printCommand);
    Tcl_DStringAppend(printCommand, printDocProc, -1);
    Tcl_DStringAppendElement(printCommand, printFile);
    AEInfo->interp = _eventInterp;
    AEInfo->procedure = printDocProc;
    AEInfo->replyEvent = nil;
    Tcl_DoWhenIdle(ProcessAppleEvent, (ClientData)AEInfo);
    AEInfo->retryCount = 0;
    ProcessAppleEvent((ClientData)AEInfo);
}

- (void) handleDoScriptEvent: (NSAppleEventDescriptor *)event
	      withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
    OSStatus err;
    const AEDesc *theDesc = nil;
306
307
308
309
310
311
312


313
314
315
316
317
318
319
320
321
322
323
324
325
326
327

328
329
330
331




332
333
334

335
336
337

338
339
340


341
342
343
344
345
346
347
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346




347
348
349
350
351
352
353
354
355
356

357
358
359

360
361
362
363
364
365
366
367
368







+
+















+
-
-
-
-
+
+
+
+



+


-
+


-
+
+







                Tcl_DStringInit(scriptFileCommand);
                Tcl_DStringAppend(scriptFileCommand, scriptFileProc, -1);
                Tcl_DStringAppendElement(scriptFileCommand, [[fileURL path] UTF8String]);
                AEInfo->interp = _eventInterp;
                AEInfo->procedure = scriptFileProc;
                AEInfo->replyEvent = nil;
                Tcl_DoWhenIdle(ProcessAppleEvent, (ClientData)AEInfo);
		AEInfo->retryCount = 0;
                ProcessAppleEvent((ClientData)AEInfo);
            }
        }
    } else if (noErr == AEGetParamPtr(theDesc, keyDirectObject, typeUTF8Text, &type,
			       NULL, 0, &actual)) {
        /*
         * The descriptor cannot be coerced to a file URL but can be coerced to
         * text.  Construct a Tcl expression which passes the text as a string
         * argument to ::tk::mac::DoScriptText.
         */

	if (actual > 0) {
	    char *data = (char *)ckalloc(actual + 1);
	    if (noErr == AEGetParamPtr(theDesc, keyDirectObject,
				       typeUTF8Text, &type,
				       data, actual, NULL)) {
		data[actual] = '\0';
                AppleEventInfo *AEInfo = (AppleEventInfo *)ckalloc(sizeof(AppleEventInfo));
                Tcl_DString *scriptTextCommand = &AEInfo->command;
                Tcl_DStringInit(scriptTextCommand);
                Tcl_DStringAppend(scriptTextCommand, scriptTextProc, -1);
		AppleEventInfo *AEInfo = (AppleEventInfo *)ckalloc(sizeof(AppleEventInfo));
		Tcl_DString *scriptTextCommand = &AEInfo->command;
		Tcl_DStringInit(scriptTextCommand);
		Tcl_DStringAppend(scriptTextCommand, scriptTextProc, -1);
		Tcl_DStringAppendElement(scriptTextCommand, data);
		AEInfo->interp = _eventInterp;
		AEInfo->procedure = scriptTextProc;
		AEInfo->retryCount = 0;
                if (Tcl_FindCommand(AEInfo->interp, AEInfo->procedure, NULL, 0)) {
                    AEInfo->replyEvent = replyEvent;
                    ProcessAppleEvent((ClientData)AEInfo);
                    ProcessAppleEvent(AEInfo);
                } else {
                    AEInfo->replyEvent = nil;
                    Tcl_DoWhenIdle(ProcessAppleEvent, (ClientData)AEInfo);
                    Tcl_DoWhenIdle(ProcessAppleEvent, AEInfo);
                    ProcessAppleEvent(AEInfo);
                }
	    }
	}
    }
}

- (void)handleURLEvent:(NSAppleEventDescriptor*)event
357
358
359
360
361
362
363


364
365
366
367
368
369
370
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393







+
+







    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 -

/*
391
392
393
394
395
396
397

398
399



















400
401
402
403
404
405
406
407
408
409
410
411
412
413
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
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444



445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469







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




-
-
-














+
+

+







 */

static void ProcessAppleEvent(
    ClientData clientData)
{
    int code;
    AppleEventInfo *AEInfo = (AppleEventInfo*) clientData;

    if (!AEInfo->interp ||
        !Tcl_FindCommand(AEInfo->interp, AEInfo->procedure, NULL, 0)) {
    if (!AEInfo->interp) {
	return;
    }

    /*
     * Apple events that are delivered during the app startup can arrive
     * before the Tcl procedure for handling the events has been defined.
     * If the command is not found we create a timer handler to process
     * the event later, hopefully after the command has been created.
     * We retry up to 2 times before giving up.
     */

    if (!Tcl_FindCommand(AEInfo->interp, AEInfo->procedure, NULL, 0)) {
	if (AEInfo->retryCount < 2) {
	    AEInfo->retryCount++;
	    Tcl_CreateTimerHandler(200, ProcessAppleEvent, clientData);
	} else {
	    ckfree(clientData);
	}
	return;
    }
    code = Tcl_EvalEx(AEInfo->interp, Tcl_DStringValue(&AEInfo->command),
	    Tcl_DStringLength(&AEInfo->command), TCL_EVAL_GLOBAL);
    if (code != TCL_OK) {
	Tcl_BackgroundException(AEInfo->interp, code);
    }

    if (AEInfo->replyEvent && code >= 0) {
        int reslen;
        const char *result = Tcl_GetStringFromObj(Tcl_GetObjResult(AEInfo->interp),
                                                  &reslen);
        if (code == TCL_OK) {
            AEPutParamPtr((AppleEvent*)[AEInfo->replyEvent aeDesc],
                          keyDirectObject, typeChar, result, reslen);
        } else {
            AEPutParamPtr((AppleEvent*)[AEInfo->replyEvent aeDesc],
                          keyErrorString, typeChar, result, reslen);
            AEPutParamPtr((AppleEvent*)[AEInfo->replyEvent aeDesc],
                          keyErrorNumber, typeSInt32, (Ptr) &code, sizeof(int));
        }
    } else if (code != TCL_OK) {
	Tcl_BackgroundException(AEInfo->interp, code);
    }

    Tcl_DStringFree(&AEInfo->command);
    ckfree(clientData);
}

/*
 *----------------------------------------------------------------------
 *
438
439
440
441
442
443
444
445

446
447
448
449
450
451
452
453
454
455
456
479
480
481
482
483
484
485

486
487
488
489

490
491
492
493
494
495
496







-
+



-







 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXInitAppleEvents(
    Tcl_Interp *dummy)   /* not used */
    TCL_UNUSED(Tcl_Interp *))
{
    NSAppleEventManager *aeManager = [NSAppleEventManager sharedAppleEventManager];
    static Boolean initialized = FALSE;
    (void)dummy;

    if (!initialized) {
	initialized = TRUE;

	[aeManager setEventHandler:NSApp
	    andSelector:@selector(handleQuitApplicationEvent:withReplyEvent:)
	    forEventClass:kCoreEventClass andEventID:kAEQuitApplication];
549
550
551
552
553
554
555
556

557
558
559
560
561
562






563

564
565
566
567
568
569
570
589
590
591
592
593
594
595

596
597
598
599



600
601
602
603
604
605
606
607
608
609
610
611
612
613
614







-
+



-
-
-
+
+
+
+
+
+

+







 *
 *----------------------------------------------------------------------
 */

static int
ReallyKillMe(
    Tcl_Event *eventPtr,
    int flags)
    TCL_UNUSED(int))
{
    Tcl_Interp *interp = ((KillEvent *) eventPtr)->interp;
    int quit = Tcl_FindCommand(interp, "::tk::mac::Quit", NULL, 0)!=NULL;
    int code = Tcl_EvalEx(interp, quit ? "::tk::mac::Quit" : "exit", -1, TCL_EVAL_GLOBAL);
    (void)flags;


    if (!quit) {
	Tcl_Exit(0);
    }

    int code = Tcl_EvalEx(interp, "::tk::mac::Quit", -1, TCL_EVAL_GLOBAL);
    if (code != TCL_OK) {

	/*
	 * Should be never reached...
	 */

	Tcl_BackgroundException(interp, code);
    }
    return 1;

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49





50
51
52
53
54
55
56
1
2
3
4
5




6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27


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




48
49
50
51
52
53
54
55
56
57
58
59





-
-
-
-
+
+
+
+








+
+
+
+




-
+

-
-




















-
-
-
-
+
+
+
+
+







/*
 * 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 <[email protected]>
 * Copyright 2017-2018 Marc Culler.
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009, Apple Inc.
 * Copyright © 2005-2009 Daniel A. Steffen <[email protected]>
 * Copyright © 2017-2020 Marc Culler.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "xbytes.h"

static CGImageRef CreateCGImageFromPixmap(Drawable pixmap);
static CGImageRef CreateCGImageFromDrawableRect( Drawable drawable,
	   int x, int y, unsigned int width, unsigned int height);

#pragma mark XImage handling

int
_XInitImageFuncPtrs(
    XImage *image)
    TCL_UNUSED(XImage *)) /* image */
{
    (void)image;

    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXCreateCGImageWithXImage --
 *
 *	Create CGImage from XImage, copying the image data.  Called
 *      in Tk_PutImage and (currently) nowhere else.
 *
 * Results:
 *	CGImage, release after use.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void ReleaseData(void *info, const void *data, size_t size) {
    (void)data;
    (void)size;

static void ReleaseData(
    void *info,
    TCL_UNUSED(const void *), /* data */
    TCL_UNUSED(size_t))       /* size */
{
    ckfree(info);
}

CGImageRef
TkMacOSXCreateCGImageWithXImage(
    XImage *image)
{
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
135
136
137
138
139
140
141








































































































































142
143
144
145
146
147
148







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







    }
    return img;
}

/*
 *----------------------------------------------------------------------
 *
 * XGetImage --
 *
 *	This function copies data from a pixmap or window into an XImage.  It
 *      is essentially never used. At one time it was called by
 *      pTkImgPhotoDisplay, but that is no longer the case. Currently it is
 *      called two places, one of which is requesting an XY image which we do
 *      not support.  It probably does not work correctly -- see the comments
 *      for TkMacOSXBitmapRepFromDrawableRect.
 *
 * Results:
 *	Returns a newly allocated XImage containing the data from the given
 *	rectangle of the given drawable, or NULL if the XImage could not be
 *	constructed.  NOTE: If we are copying from a window on a Retina
 *	display, the dimensions of the XImage will be 2*width x 2*height.
 *
 * 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,
    unsigned long plane_mask,
    int format)
{
    NSBitmapImageRep* bitmap_rep = NULL;
    NSUInteger bitmap_fmt = 0;
    XImage* imagePtr = NULL;
    char* bitmap = NULL;
    char R, G, B, A;
    int depth = 32, offset = 0, bitmap_pad = 0;
    unsigned int bytes_per_row, size, row, n, m;
    unsigned int scalefactor=1, scaled_height=height, scaled_width=width;
    NSWindow *win = TkMacOSXDrawableWindow(drawable);
    static enum {unknown, no, yes} has_retina = unknown;
    (void)plane_mask;

    if (win && has_retina == unknown) {
#ifdef __clang__
	has_retina = [win respondsToSelector:@selector(backingScaleFactor)] ?
		yes : no;
#else
	has_retina = no;
#endif
    }

    if (has_retina == yes) {
	/*
	 * We only allow scale factors 1 or 2, as Apple currently does.
	 */

#ifdef __clang__
	scalefactor = [win backingScaleFactor] == 2.0 ? 2 : 1;
#endif
	scaled_height *= scalefactor;
	scaled_width *= scalefactor;
    }

    if (format == ZPixmap) {
	if (width == 0 || height == 0) {
	    return NULL;
	}

	bitmap_rep = TkMacOSXBitmapRepFromDrawableRect(drawable,
		x, y, width, height);
	if (!bitmap_rep) {
	    TkMacOSXDbgMsg("XGetImage: Failed to construct NSBitmapRep");
	    return NULL;
	}
	bitmap_fmt = [bitmap_rep bitmapFormat];
	size = [bitmap_rep bytesPerPlane];
	bytes_per_row = [bitmap_rep bytesPerRow];
	bitmap = (char *)ckalloc(size);
	if (!bitmap
		|| (bitmap_fmt != 0 && bitmap_fmt != 1)
		|| [bitmap_rep samplesPerPixel] != 4
		|| [bitmap_rep isPlanar] != 0
		|| bytes_per_row < 4 * scaled_width
		|| size != bytes_per_row * scaled_height) {
	    TkMacOSXDbgMsg("XGetImage: Unrecognized bitmap format");
	    CFRelease(bitmap_rep);
	    return NULL;
	}
	memcpy(bitmap, (char *)[bitmap_rep bitmapData], size);
	CFRelease(bitmap_rep);

	/*
	 * When Apple extracts a bitmap from an NSView, it may be in either
	 * BGRA or ABGR format.  For an XImage we need RGBA.
	 */

	struct pixel_fmt pixel = bitmap_fmt == 0 ? bgra : abgr;

	for (row = 0, n = 0; row < scaled_height; row++, n += bytes_per_row) {
	    for (m = n; m < n + 4*scaled_width; m += 4) {
		R = *(bitmap + m + pixel.r);
		G = *(bitmap + m + pixel.g);
		B = *(bitmap + m + pixel.b);
		A = *(bitmap + m + pixel.a);

		*(bitmap + m)     = R;
		*(bitmap + m + 1) = G;
		*(bitmap + m + 2) = B;
		*(bitmap + m + 3) = A;
	    }
	}
	imagePtr = XCreateImage(display, NULL, depth, format, offset,
		(char*) bitmap, scaled_width, scaled_height,
		bitmap_pad, bytes_per_row);
	if (scalefactor == 2) {
	    imagePtr->pixelpower = 1;
	}
    } 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;
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyImage --
 *
 *	Destroys storage associated with an image.
 *
 * Results:
 *	None.
 *
302
303
304
305
306
307
308

309




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





325
326
327
328
329
330
331

332
333
334
335
336
337
338
339
340
341

342
343
344
345
346

347
348
349
350
351
352
353
354

355
356
357
358
359
360
361
362

363
364
365
366
367


368
369
370
371
372
373
374
169
170
171
172
173
174
175
176

177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206

207
208
209
210
211
212
213
214
215
216

217
218
219
220
221

222
223
224
225
226
227
228
229

230
231
232
233
234
235
236
237

238
239
240
241
242

243
244
245
246
247
248
249
250
251







+
-
+
+
+
+















+
+
+
+
+






-
+









-
+




-
+







-
+







-
+




-
+
+







 *----------------------------------------------------------------------
 *
 * ImageGetPixel --
 *
 *	Get a single pixel from an image.
 *
 * Results:
 *      The XColor structure contains an unsigned long field named pixel which
 *	Returns the 32 bit pixel value.
 *      identifies the color.  This function returns the unsigned long that
 *      would be used as the pixel value of an XColor that has the same red
 *      green and blue components as the XImage pixel at the specified
 *      location.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static unsigned long
ImageGetPixel(
    XImage *image,
    int x,
    int y)
{
    unsigned char r = 0, g = 0, b = 0;

    /*
     * Compute 8 bit red green and blue values, which are passed as inputs to
     * TkMacOSXRGBPixel to produce the pixel value.
     */

    if (image && image->data) {
	unsigned char *srcPtr = ((unsigned char*) image->data)
		+ (y * image->bytes_per_line)
		+ (((image->xoffset + x) * image->bits_per_pixel) / NBBY);

	switch (image->bits_per_pixel) {
	case 32:
	case 32: /* 8 bits per channel */
	    r = (*((unsigned int*) srcPtr) >> 16) & 0xff;
	    g = (*((unsigned int*) srcPtr) >>  8) & 0xff;
	    b = (*((unsigned int*) srcPtr)      ) & 0xff;
	    /*if (image->byte_order == LSBFirst) {
		r = srcPtr[2]; g = srcPtr[1]; b = srcPtr[0];
	    } else {
		r = srcPtr[1]; g = srcPtr[2]; b = srcPtr[3];
	    }*/
	    break;
	case 16:
	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:
	case 8: /* 2 bits per channel */
	    r = (*srcPtr << 2) & 0xc0;
	    g = (*srcPtr << 4) & 0xc0;
	    b = (*srcPtr << 6) & 0xc0;
	    r |= r >> 2 | r >> 4 | r >> 6;
	    g |= g >> 2 | g >> 4 | g >> 6;
	    b |= b >> 2 | b >> 4 | b >> 6;
	    break;
	case 4: {
	case 4: { /* 1 bit per channel */
	    unsigned char c = (x % 2) ? *srcPtr : (*srcPtr >> 4);

	    r = (c & 0x04) ? 0xff : 0;
	    g = (c & 0x02) ? 0xff : 0;
	    b = (c & 0x01) ? 0xff : 0;
	    break;
	}
	case 1:
	case 1: /* Black-white bitmap. */
	    r = g = b = ((*srcPtr) & (0x80 >> (x % 8))) ? 0xff : 0;
	    break;
	}
    }
    return (PIXEL_MAGIC << 24) | (r << 16) | (g << 8) | b;

    return TkMacOSXRGBPixel(r, g, b);
}

/*
 *----------------------------------------------------------------------
 *
 * ImagePutPixel --
 *
442
443
444
445
446
447
448
449

450
451
452
453
454
455
456
457
458
459
460
461
462
463

464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
319
320
321
322
323
324
325

326
327
328
329
330
331
332
333
334
335
336

337
338

339
340
341
342
343
344
345
346
347
348







349
350
351
352
353
354
355







-
+










-


-
+









-
-
-
-
-
-
-







 *
 *----------------------------------------------------------------------
 */

XImage *
XCreateImage(
    Display* display,
    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;
    (void)visual;

    display->request++;
    ximage = (XImage *)ckalloc(sizeof(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;

    /*
     * The default pixelpower is 0.  This must be explicitly set to 1 in the
     * case of an XImage extracted from a Retina display.
     */

    ximage->pixelpower = 0;

    if (format == ZPixmap) {
	ximage->bits_per_pixel = 32;
	ximage->bitmap_unit = 32;
    } else {
	ximage->bits_per_pixel = 1;
	ximage->bitmap_unit = 8;
    }
545
546
547
548
549
550
551
552

553
554
555

556
557
558

559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584

585
586
587
588
589
590
591
592
593
594
595
596
597
598
































































































































































































































































































































































































































































599
600
601
602
603
604
605
606
607
414
415
416
417
418
419
420

421
422
423

424
425
426

427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442









443

444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
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







-
+


-
+


-
+















-
-
-
-
-
-
-
-
-

-
+














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









    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;
    MacDrawable *macDraw = (MacDrawable *)drawable;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(drawable, gc, 1, &dc)) {
    if (!TkMacOSXSetupDrawingContext(drawable, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect bounds, srcRect, dstRect;
	CGImageRef img = TkMacOSXCreateCGImageWithXImage(image);

	/*
	 * The CGContext for a pixmap is RGB only, with A = 0.
	 */

	if (!(macDraw->flags & TK_IS_PIXMAP)) {
	    CGContextSetBlendMode(dc.context, kCGBlendModeSourceAtop);
	}
	if (img) {

	    /*
	     * If the XImage has big pixels, the source is rescaled to reflect
	     * the actual pixel dimensions.  This is not currently used, but
	     * could arise if the image were copied from a retina monitor and
	     * redrawn on an ordinary monitor.
	     */

	    int pp = image->pixelpower;

	    bounds = CGRectMake(0, 0, image->width, image->height);
	    srcRect = CGRectMake(src_x<<pp, src_y<<pp, width<<pp, height<<pp);
	    srcRect = CGRectMake(src_x, src_y, width, height);
	    dstRect = CGRectMake(dest_x, dest_y, width, height);
	    TkMacOSXDrawCGImage(drawable, gc, dc.context,
				img, gc->foreground, gc->background,
				bounds, srcRect, dstRect);
	    CFRelease(img);
	} else {
	    TkMacOSXDbgMsg("Invalid source drawable");
	}
    } else {
	TkMacOSXDbgMsg("Invalid destination drawable");
    }
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * CreateCGImageFromDrawableRect
 *
 *	Extract image data from a MacOSX drawable as a CGImage.
 *
 *      This is only called by XGetImage and XCopyArea.  The Tk core uses
 *      these functions on some platforms, but on macOS the core does not
 *      call them with a source drawable which is a window.  Such calls are
 *      used only for double-buffered drawing.  Since macOS defines the
 *      macro TK_NO_DOUBLE_BUFFERING, the generic code never calls XGetImage
 *      or XCopyArea on macOS.  Nonetheless, these function are in the stubs
 *      table and therefore could be used by extensions.
 *
 *      This implementation does not work correctly.  Originally it relied on
 *      [NSBitmapImageRep initWithFocusedViewRect:view_rect] which was
 *      deprecated by Apple in OSX 10.14 and also required the use of other
 *      deprecated functions such as [NSView lockFocus]. Apple's suggested
 *      replacement is [NSView cacheDisplayInRect: toBitmapImageRep:] and that
 *      is what is being used here.  However, that method only works when the
 *      view has a valid CGContext, and a view is only guaranteed to have a
 *      valid context during a call to [NSView drawRect]. To further complicate
 *      matters, cacheDisplayInRect calls [NSView drawRect]. Essentially it is
 *      asking the view to draw a subrectangle of itself using a special
 *      graphics context which is linked to the BitmapImageRep. But our
 *      implementation of [NSView drawRect] does not allow recursive calls. If
 *      called recursively it returns immediately without doing any drawing.
 *      So the bottom line is that this function either returns a NULL pointer
 *      or a black image. To make it useful would require a significant amount
 *      of rewriting of the drawRect method. Perhaps the next release of OSX
 *      will include some more helpful ways of doing this.
 *
 * Results:
 *	Returns an NSBitmapRep representing the image of the given rectangle of
 *      the given drawable. This object is retained. The caller is responsible
 *      for releasing it.
 *
 *      NOTE: The x,y coordinates should be relative to a coordinate system
 *      with origin at the top left, as used by XImage and CGImage, not bottom
 *      left as used by NSView.
 *
 * Side effects:
 *     None
 *
 *----------------------------------------------------------------------
 */

static CGImageRef
CreateCGImageFromDrawableRect(
    Drawable drawable,
    int x,
    int y,
    unsigned int width,
    unsigned int height)
{
    MacDrawable *mac_drawable = (MacDrawable *)drawable;
    CGContextRef cg_context = NULL;
    CGImageRef cg_image = NULL, result = NULL;
    NSBitmapImageRep *bitmapRep = nil;
    NSView *view = nil;
    if (mac_drawable->flags & TK_IS_PIXMAP) {
	/*
	 * This MacDrawable is a bitmap, so its view is NULL.
	 */

	CGRect image_rect = CGRectMake(x, y, width, height);

	cg_context = TkMacOSXGetCGContextForDrawable(drawable);
	cg_image = CGBitmapContextCreateImage((CGContextRef) cg_context);
	if (cg_image) {
	    result = CGImageCreateWithImageInRect(cg_image, image_rect);
	    CGImageRelease(cg_image);
	}
    } else if (TkMacOSXGetNSViewForDrawable(mac_drawable) != nil) {

	/*
	 * Convert Tk top-left to NSView bottom-left coordinates.
	 */

	int view_height = [view bounds].size.height;
	NSRect view_rect = NSMakeRect(x + mac_drawable->xOff,
		view_height - height - y - mac_drawable->yOff,
		width, height);

	/*
	 * Attempt to copy from the view to a bitmapImageRep.  If the view does
	 * not have a valid CGContext, doing this will silently corrupt memory
	 * and make a big mess. So, in that case, we just return NULL.
	 */

	if (view == [NSView focusView]) {
	    bitmapRep = [view bitmapImageRepForCachingDisplayInRect: view_rect];
	    [view cacheDisplayInRect:view_rect toBitmapImageRep:bitmapRep];
	    result = [bitmapRep CGImage];
	    CFRelease(bitmapRep);
	} else {
	    TkMacOSXDbgMsg("No CGContext - cannot copy from screen to bitmap.");
	    result = NULL;
	}
    } else {
	TkMacOSXDbgMsg("Invalid source drawable");
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * CreateCGImageFromPixmap --
 *
 *	Create a CGImage from an X Pixmap.
 *
 * Results:
 *	CGImage, release after use.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static CGImageRef
CreateCGImageFromPixmap(
    Drawable pixmap)
{
    CGImageRef img = NULL;
    CGContextRef context = TkMacOSXGetCGContextForDrawable(pixmap);

    if (context) {
	img = CGBitmapContextCreateImage(context);
    }
    return img;
}

/*
 *----------------------------------------------------------------------
 *
 * XGetImage --
 *
 *	This function copies data from a pixmap or window into an XImage.  It
 *      is essentially never used. At one time it was called by
 *      pTkImgPhotoDisplay, but that is no longer the case. Currently it is
 *      called two places, one of which is requesting an XY image which we do
 *      not support.  It probably does not work correctly -- see the comments
 *      for CGImageFromDrawableRect.
 *
 * Results:
 *	Returns a newly allocated XImage containing the data from the given
 *	rectangle of the given drawable, or NULL if the XImage could not be
 *	constructed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */
struct pixel_fmt {int r; int g; int b; int a;};
static struct pixel_fmt bgra = {2, 1, 0, 3};
static struct pixel_fmt abgr = {3, 2, 1, 0};

XImage *
XGetImage(
    Display *display,
    Drawable drawable,
    int x,
    int y,
    unsigned int width,
    unsigned int height,
    TCL_UNUSED(unsigned long), /* plane_mask */
    int format)
{
    NSBitmapImageRep* bitmapRep = nil;
    NSUInteger bitmap_fmt = 0;
    XImage* imagePtr = NULL;
    char* bitmap = NULL;
    char R, G, B, A;
    int depth = 32, offset = 0, bitmap_pad = 0;
    unsigned int bytes_per_row, size, row, n, m;

    if (format == ZPixmap) {
	CGImageRef cgImage;
	if (width == 0 || height == 0) {
	    return NULL;
	}

	cgImage = CreateCGImageFromDrawableRect(drawable, x, y, width, height);
	if (cgImage) {
	    bitmapRep = [NSBitmapImageRep alloc];
	    [bitmapRep initWithCGImage:cgImage];
	    CFRelease(cgImage);
	} else {
	    TkMacOSXDbgMsg("XGetImage: Failed to construct CGImage");
	    return NULL;
	}
	bitmap_fmt = [bitmapRep bitmapFormat];
	size = [bitmapRep bytesPerPlane];
	bytes_per_row = [bitmapRep bytesPerRow];
	bitmap = ckalloc(size);
	if (!bitmap
		|| (bitmap_fmt != 0 && bitmap_fmt != 1)
		|| [bitmapRep samplesPerPixel] != 4
		|| [bitmapRep isPlanar] != 0
		|| bytes_per_row < 4 * width
		|| size != bytes_per_row * height) {
	    TkMacOSXDbgMsg("XGetImage: Unrecognized bitmap format");
	    CFRelease(bitmapRep);
	    return NULL;
	}
	memcpy(bitmap, (char *)[bitmapRep bitmapData], size);
	CFRelease(bitmapRep);

	/*
	 * When Apple extracts a bitmap from an NSView, it may be in either
	 * BGRA or ABGR format.  For an XImage we need RGBA.
	 */

	struct pixel_fmt pixel = bitmap_fmt == 0 ? bgra : abgr;

	for (row = 0, n = 0; row < height; row++, n += bytes_per_row) {
	    for (m = n; m < n + 4*width; m += 4) {
		R = *(bitmap + m + pixel.r);
		G = *(bitmap + m + pixel.g);
		B = *(bitmap + m + pixel.b);
		A = *(bitmap + m + pixel.a);

		*(bitmap + m)     = R;
		*(bitmap + m + 1) = G;
		*(bitmap + m + 2) = B;
		*(bitmap + m + 3) = A;
	    }
	}
	imagePtr = XCreateImage(display, NULL, depth, format, offset,
		(char*) bitmap, width, height,
		bitmap_pad, bytes_per_row);
    } else {
	/*
	 * There are some calls to XGetImage in the generic Tk code which pass
	 * an XYPixmap rather than a ZPixmap.  XYPixmaps should be handled
	 * here.
	 */
	TkMacOSXDbgMsg("XGetImage does not handle XYPixmaps at the moment.");
    }
    return imagePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * XCopyArea --
 *
 *	Copies image data from one drawable to another.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Image data is moved from a window or bitmap to a second window or bitmap.
 *
 *----------------------------------------------------------------------
 */

int
XCopyArea(
    Display *display,		/* Display. */
    Drawable src,		/* Source drawable. */
    Drawable dst,		/* Destination drawable. */
    GC gc,			/* GC to use. */
    int src_x,			/* X & Y, width & height */
    int src_y,			/* define the source rectangle */
    unsigned int width,		/* that will be copied. */
    unsigned int height,
    int dest_x,			/* Dest X & Y on dest rect. */
    int dest_y)
{
    TkMacOSXDrawingContext dc;
    MacDrawable *srcDraw = (MacDrawable *)src;
    CGImageRef img = NULL;
    CGRect bounds, srcRect, dstRect;

    display->request++;
    if (!width || !height) {
	return BadDrawable;
    }

    if (!TkMacOSXSetupDrawingContext(dst, gc, &dc)) {
	TkMacOSXDbgMsg("Failed to setup drawing context.");
	return BadDrawable;
    }

    if (!dc.context) {
	TkMacOSXDbgMsg("Invalid destination drawable - no context.");
	return BadDrawable;
    }

    if (srcDraw->flags & TK_IS_PIXMAP) {
	img = CreateCGImageFromPixmap(src);
    } else if (TkMacOSXGetNSWindowForDrawable(src)) {
	img = CreateCGImageFromDrawableRect(src, src_x, src_y, width, height);
    } else {
	TkMacOSXDbgMsg("Invalid source drawable - neither window nor pixmap.");
    }

    if (img) {
	bounds = CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height);
	srcRect = CGRectMake(src_x, src_y, width, height);
	dstRect = CGRectMake(dest_x, dest_y, width, height);
	TkMacOSXDrawCGImage(dst, gc, dc.context, img,
		gc->foreground, gc->background, bounds, srcRect, dstRect);
	CFRelease(img);
    } else {
	TkMacOSXDbgMsg("Failed to construct CGImage.");
    }

    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XCopyPlane --
 *
 *	Copies a bitmap from a source drawable to a destination drawable. The
 *	plane argument specifies which bit plane of the source contains the
 *	bitmap. Note that this implementation ignores the gc->function.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Changes the destination drawable.
 *
 *----------------------------------------------------------------------
 */

int
XCopyPlane(
    Display *display,		/* Display. */
    Drawable src,		/* Source drawable. */
    Drawable dst,		/* Destination drawable. */
    GC gc,				/* GC to use. */
    int src_x,			/* X & Y, width & height */
    int src_y,			/* define the source rectangle */
    unsigned int width,	/* that will be copied. */
    unsigned int height,
    int dest_x,			/* Dest X & Y on dest rect. */
    int dest_y,
    unsigned long plane)	/* Which plane to copy. */
{
    TkMacOSXDrawingContext dc;
    MacDrawable *srcDraw = (MacDrawable *)src;
    MacDrawable *dstDraw = (MacDrawable *)dst;
    CGRect bounds, srcRect, dstRect;
    display->request++;
    if (!width || !height) {
	/* TkMacOSXDbgMsg("Drawing of empty area requested"); */
	return BadDrawable;
    }
    if (plane != 1) {
	Tcl_Panic("Unexpected plane specified for XCopyPlane");
    }
    if (srcDraw->flags & TK_IS_PIXMAP) {
	if (!TkMacOSXSetupDrawingContext(dst, gc, &dc)) {
	    return BadDrawable;
	}

	CGContextRef context = dc.context;

	if (context) {
	    CGImageRef img = CreateCGImageFromPixmap(src);

	    if (img) {
		TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask;
		unsigned long imageBackground  = gc->background;

                if (clipPtr && clipPtr->type == TKP_CLIP_PIXMAP) {
		    srcRect = CGRectMake(src_x, src_y, width, height);
		    CGImageRef mask = CreateCGImageFromPixmap(
			    clipPtr->value.pixmap);
		    CGImageRef submask = CGImageCreateWithImageInRect(
			    img, srcRect);
		    CGRect rect = CGRectMake(dest_x, dest_y, width, height);

		    rect = CGRectOffset(rect, dstDraw->xOff, dstDraw->yOff);
		    CGContextSaveGState(context);

		    /*
		     * Move the origin of the destination to top left.
		     */

		    CGContextTranslateCTM(context,
			    0, rect.origin.y + CGRectGetMaxY(rect));
		    CGContextScaleCTM(context, 1, -1);

		    /*
		     * Fill with the background color, clipping to the mask.
		     */

		    CGContextClipToMask(context, rect, submask);
		    TkMacOSXSetColorInContext(gc, gc->background, dc.context);
		    CGContextFillRect(context, rect);

		    /*
		     * Fill with the foreground color, clipping to the
		     * intersection of img and mask.
		     */

		    CGImageRef subimage = CGImageCreateWithImageInRect(
			    img, srcRect);
		    CGContextClipToMask(context, rect, subimage);
		    TkMacOSXSetColorInContext(gc, gc->foreground, context);
		    CGContextFillRect(context, rect);
		    CGContextRestoreGState(context);
		    CGImageRelease(img);
		    CGImageRelease(mask);
		    CGImageRelease(submask);
		    CGImageRelease(subimage);
		} else {
		    bounds = CGRectMake(0, 0,
			    srcDraw->size.width, srcDraw->size.height);
		    srcRect = CGRectMake(src_x, src_y, width, height);
		    dstRect = CGRectMake(dest_x, dest_y, width, height);
		    TkMacOSXDrawCGImage(dst, gc, dc.context, img,
			    gc->foreground, imageBackground, bounds,
			    srcRect, dstRect);
		    CGImageRelease(img);
		}
	    } else {
		/* no image */
		TkMacOSXDbgMsg("Invalid source drawable");
	    }
	} else {
	    TkMacOSXDbgMsg("Invalid destination drawable - "
		    "could not get a bitmap context.");
	}
	TkMacOSXRestoreDrawingContext(&dc);
	return Success;
    } else {
	/*
	 * Source drawable is a Window, not a Pixmap.
	 */

	return XCopyArea(display, src, dst, gc, src_x, src_y, width, height,
		dest_x, dest_y);
    }
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXInit.c.

1
2
3
4
5
6
7
8
9
10




11
12
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
1
2
3
4
5
6




7
8
9
10
11
12
13
14
15
16


17
18
19
20
21
22
23
24
25
26






-
-
-
-
+
+
+
+






-
-


+







/*
 * 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 <[email protected]>
 * Copyright (c) 2017 Marc Culler
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2005-2009 Daniel A. Steffen <[email protected]>
 * 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 <sys/stat.h>
#include <dlfcn.h>
#include <objc/objc-auto.h>
#include <sys/stat.h>

static char tkLibPath[PATH_MAX + 1] = "";

/*
 * If the App is in an App package, then we want to add the Scripts directory
 * to the auto_path.
 */
37
38
39
40
41
42
43


44
45
46
47
48
49
50
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51







+
+








#pragma mark TKApplication(TKInit)

@implementation TKApplication
@synthesize poolLock = _poolLock;
@synthesize macOSVersion = _macOSVersion;
@synthesize isDrawing = _isDrawing;
@synthesize needsToDraw = _needsToDraw;
@synthesize isSigned = _isSigned;
@end

/*
 * #define this to see a message on stderr whenever _resetAutoreleasePool is
 * called while the pool is locked.
 */
#undef DEBUG_LOCK
99
100
101
102
103
104
105
106
107
108



109
110


111
112
113
114
115




116
117
118
119
120
121
122
123
124
125
126





127


128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147

148
149
150
151
152
153
154
100
101
102
103
104
105
106



107
108
109


110
111

112



113
114
115
116
117
118
119
120
121
122
123




124
125
126
127
128

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
157







-
-
-
+
+
+
-
-
+
+
-

-
-
-
+
+
+
+







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



















-
+







     */
#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.
}

-(void)applicationDidFinishLaunching:(NSNotification *)notification
     */
    _defaultMainMenu = nil;
{
    (void)notification;
    [self _setupMenus];

    /*
     * Initialize event processing.
     */
   /*
    * Initialize event processing.
    */

    TkMacOSXInitAppleEvents(_eventInterp);

    /*
     * Initialize the graphics context.
     */
    TkMacOSXUseAntialiasedText(_eventInterp, -1);
    TkMacOSXInitCGDrawing(_eventInterp, TRUE, 0);
}

-(void)applicationDidFinishLaunching:(NSNotification *)notification
{

    /*
     * Construct the menu bar.
     */

    (void)notification;
    _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];

    /*
     * Process events to ensure that the root window is fully initialized. See
     * ticket 56a1823c73.
     */

    [NSApp _lockAutoreleasePool];
    while (Tcl_DoOneEvent(TCL_WINDOW_EVENTS| TCL_DONT_WAIT)) {}
    while (Tcl_DoOneEvent(TCL_WINDOW_EVENTS|TCL_DONT_WAIT)) {}
    [NSApp _unlockAutoreleasePool];
}

- (void) _setup: (Tcl_Interp *) interp
{
    /*
     * Remember our interpreter.
197
198
199
200
201
202
203

204
205
206
207
208
209
210
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214







+







    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];
	    }
	}
    }
}

265
266
267
268
269
270
271
272










































































273
274
275
276
277
278
279
280
281


282
283
284
285
286
287
288



289
290
291
292
293
294
295
296
297


298

299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342

343
344
345
346
347
348
349
350








351
352

353
354
355
356
357
358
359
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357


358
359

360
361
362
363


364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394










395
396
397
398
399
400
401
402
403
404
405
406
407
408
409

410
411

412








413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430








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







-
-
+
+
-




-
-
+
+
+









+
+

+















-
-
-
-
-
-
-
-
-
-















-


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


+







 *	the interp's result.
 *
 * Side effects:
 *	Sets "tk_library" Tcl variable, runs "tk.tcl" script.
 *
 *----------------------------------------------------------------------
 */

/*
 * Helper function which closes the shared NSFontPanel and NSColorPanel.
 */

static void closePanels(
    void)
{
    if ([NSFontPanel sharedFontPanelExists]) {
	[[NSFontPanel sharedFontPanel] orderOut:nil];
    }
    if ([NSColorPanel sharedColorPanelExists]) {
        [[NSColorPanel sharedColorPanel] orderOut:nil];
    }
}

/*
 * This custom exit procedure is called by Tcl_Exit in place of the exit
 * function from the C runtime.  It calls the terminate method of the
 * NSApplication class (superTerminate for a TKApplication).  The purpose of
 * doing this is to ensure that the NSFontPanel and the NSColorPanel are closed
 * before the process exits, and that the application state is recorded
 * correctly for all termination scenarios.
 *
 * TkpWantsExitProc tells Tcl_AppInit whether to install our custom exit proc,
 * which terminates the process by calling [NSApplication terminate].  This
 * does not work correctly if the process is part of an exec pipeline, so it is
 * only done if the process was launched by the launcher or if both stdin and
 * stdout are ttys.  To disable using the custom exit proc altogether, undefine
 * USE_CUSTOM_EXIT_PROC.
 */

#if defined(USE_CUSTOM_EXIT_PROC)
static Bool doCleanupFromExit = NO;

int TkpWantsExitProc(void) {
    return doCleanupFromExit == YES;
}

TCL_NORETURN void TkpExitProc(
    void *clientdata)
{
    Bool doCleanup = doCleanupFromExit;
    if (doCleanupFromExit) {
	doCleanupFromExit = NO; /* prevent possible recursive call. */
	closePanels();
    }

    /*
     * Tcl_Exit does not call Tcl_Finalize if there is an exit proc installed.
     */

    Tcl_Finalize();
    if (doCleanup == YES) {
	[(TKApplication *)NSApp superTerminate:nil]; /* Should not return. */
    }
    exit((long)clientdata); /* Convince the compiler that we don't return. */
}
#endif

/*
 * This signal handler is installed for the SIGINT, SIGHUP and SIGTERM signals
 * so that normal finalization occurs when a Tk app is killed by one of these
 * signals (e.g when ^C is pressed while running Wish in the shell).  It calls
 * Tcl_Exit instead of the C runtime exit function called by the default handler.
 * This is consistent with the Tcl_Exit manual page, which says that Tcl_Exit
 * should always be called instead of exit.  When Tk is killed by a signal we
 * return exit status 1.
 */

static void TkMacOSXSignalHandler(TCL_UNUSED(int)) {

    Tcl_Exit(1);
}

int
TkpInit(
    Tcl_Interp *interp)
{
    static int initialized = 0;

    /*
     * Since it is possible for TkInit to be called multiple times and we
     * don't want to do the following initialization multiple times we protect
     * TkpInit can be called multiple times with different interpreters. But
     * The application initialization should only be done onece.
     * against doing it more than once.
     */

    if (!initialized) {
	struct stat st;

	initialized = 1;
	Bool shouldOpenConsole = NO;
        Bool stdinIsNullish = (!isatty(0) &&
	    (fstat(0, &st) || (S_ISCHR(st.st_mode) && st.st_blocks == 0)));

	/*
	 * Initialize/check OS version variable for runtime checks.
	 */

#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
#   error Mac OS X 10.6 required
#endif

	initialized = 1;

#ifdef TK_FRAMEWORK

	/*
	 * When Tk is in a framework, force tcl_findLibrary to look in the
	 * framework scripts directory.
	 * FIXME: Should we come up with a more generic way of doing this?
	 */

	if (Tcl_MacOSXOpenVersionedBundleResources(interp,
		"com.tcltk.tklibrary", TK_FRAMEWORK_VERSION, 0, PATH_MAX,
		tkLibPath) != TCL_OK) {
            # if 0 /* This is not really an error.  Wish still runs fine. */
	    TkMacOSXDbgMsg("Tcl_MacOSXOpenVersionedBundleResources failed");
	    # endif
	}
#endif

	/*
	 * FIXME: Close stdin & stdout for remote debugging otherwise we will
	 * fight with gdb for stdin & stdout
	 */

	if (getenv("XCNOSTDIN") != NULL) {
	    close(0);
	    close(1);
	}

	/*
	 * Instantiate our NSApplication object. This needs to be done before
	 * we check whether to open a console window.
	 */

	NSAutoreleasePool *pool = [NSAutoreleasePool new];
	[[NSUserDefaults standardUserDefaults] registerDefaults:
		[NSDictionary dictionaryWithObjectsAndKeys:
				  [NSNumber numberWithBool:YES],
			      @"_NSCanWrapButtonTitles",
				   [NSNumber numberWithInt:-1],
			      @"NSStringDrawingTypesetterBehavior",
			      nil]];
	[TKApplication sharedApplication];
	[pool drain];
	[NSApp _setup:interp];

        /*
         * WARNING: The finishLaunching method runs asynchronously, apparently
         * WARNING: The finishLaunching method runs asynchronously. This
         * in a separate thread.  This creates a race between the
         * initialization of the NSApplication and the initialization of Tk.
         * If Tk wins the race bad things happen with the root window (see
         * below).  If the NSApplication wins then an AppleEvent created during
         * launch, e.g. by dropping a file icon on the application icon, will
         * be delivered before the procedure meant to to handle the AppleEvent
         * has been defined.  This is now handled by processing the AppleEvent
         * as an idle task.  See tkMacOSXHLEvents.c.
         * creates a race between the initialization of the NSApplication and
         * the initialization of Tk.  If Tk wins the race bad things happen
         * with the root window (see below).  If the NSApplication wins then an
         * AppleEvent created during launch, e.g. by dropping a file icon on
         * the application icon, will be delivered before the procedure meant
         * to to handle the AppleEvent has been defined.  This is handled in
         * tkMacOSXHLEvents.c by scheduling a timer event to handle the
         * ApplEvent later, after the required procedure has been defined.
         */

	[NSApp _setup:interp];
	[NSApp finishLaunching];

        /*
         * Create a Tk event source based on the Appkit event queue.
         */

	Tk_MacOSXSetupTkNotifier();
372
373
374
375
376
377
378
379

380
381


382
383
384

385
386
387
388
389
390
391

392
393
394
395
396
397
398
399



400
401
402


403
404
405













406
407
408

























409
410
411
412
413
414
415
416
417
418







419
































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


435
436
437
438
439
440
441
443
444
445
446
447
448
449

450


451
452
453
454

455







456








457
458
459



460
461
462


463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512

513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576







-
+
-
-
+
+


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

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



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









-
+
+
+
+
+
+
+

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















+
+







         * NSApplication initialization wins the race, avoiding these bad
         * window behaviors.
	 */

	Tcl_DoOneEvent(TCL_WINDOW_EVENTS | TCL_DONT_WAIT);

	/*
	 * If we don't have a TTY and stdin is a special character file of
	 * Decide whether to open a console window.  If the TK_CONSOLE
	 * length 0, (e.g. /dev/null, which is what Finder sets when double
	 * clicking Wish) then use the Tk based console interpreter.
	 * environment variable is not defined we only show the console if
	 * stdin is not a tty and there is no startup script.
	 */

	if (getenv("TK_CONSOLE") ||
	if (getenv("TK_CONSOLE")) {
		(!isatty(0) && (fstat(0, &st) ||
		(S_ISCHR(st.st_mode) && st.st_blocks == 0)))) {
	    Tk_InitConsoleChannels(interp);
	    Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDIN));
	    Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDOUT));
	    Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDERR));

	    shouldOpenConsole = YES;
	    /*
	     * Only show the console if we don't have a startup script and
	     * tcl_interactive hasn't been set already.
	     */

	    if (Tcl_GetStartupScript(NULL) == NULL) {
		const char *intvar = Tcl_GetVar2(interp,
			"tcl_interactive", NULL, TCL_GLOBAL_ONLY);
	} else if (stdinIsNullish && Tcl_GetStartupScript(NULL) == NULL) {
	    const char *intvar = Tcl_GetVar2(interp, "tcl_interactive",
					     NULL, TCL_GLOBAL_ONLY);

		if (intvar == NULL) {
		    Tcl_SetVar2(interp, "tcl_interactive", NULL, "1",
	    if (intvar == NULL) {
		Tcl_SetVar2(interp, "tcl_interactive", NULL, "1",
			    TCL_GLOBAL_ONLY);
		}
	    }
	    }

#if defined(USE_CUSTOM_EXIT_PROC)
	    doCleanupFromExit = YES;
#endif

	    shouldOpenConsole = YES;
	}
	if (shouldOpenConsole) {
	    Tk_InitConsoleChannels(interp);
	    Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDIN));
	    Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDOUT));
	    Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDERR));
	    if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) {
		return TCL_ERROR;
	    }
	} else if (stdinIsNullish) {

	    /*
	     * When launched as a macOS application with no console,
	     * redirect stderr and stdout to /dev/null. This avoids waiting
	     * forever for those files to become writable if the underlying
	     * Tcl program tries to write to them with a puts command.
	     */

	    FILE *null = fopen("/dev/null", "w");
	    dup2(fileno(null), STDOUT_FILENO);
	    dup2(fileno(null), STDERR_FILENO);
#if defined(USE_CUSTOM_EXIT_PROC)
	    doCleanupFromExit = YES;
#endif
	}

	/*
	 * FIXME: Close stdin & stdout for remote debugging if XCNOSTDIN is
	 * set.  Otherwise we will fight with gdb for stdin & stdout
	 */

	if (getenv("XCNOSTDIN") != NULL) {
	    close(0);
	    close(1);
	}

	/*
	 * Initialize the NSServices object here. Apple's docs say to do this
	 * in applicationDidFinishLaunching, but the Tcl interpreter is not
	 * initialized until this function call.
	 */

	TkMacOSXServices_Init(interp);
    }

	/*
	 * The root window has been created and mapped, but XMapWindow deferred its
	 * call to makeKeyAndOrderFront because the first call to XMapWindow
	 * occurs too early in the initialization process for that.  Process idle
	 * tasks now, so the root window is configured, then order it front.
	 */

	while(Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {};
	for (NSWindow *window in [NSApp windows]) {
	    TkWindow *winPtr = TkMacOSXGetTkWindow(window);
	    if (winPtr && Tk_IsMapped(winPtr)) {
		[window makeKeyAndOrderFront:NSApp];
		break;
	    }
	}

# if defined(USE_CUSTOM_EXIT_PROC)

	if ((isatty(0) && isatty(1))) {
	    doCleanupFromExit = YES;
	}

# endif

	/*
	 * Install a signal handler for SIGINT, SIGHUP and SIGTERM which uses
	 * Tcl_Exit instead of exit so that normal cleanup takes place if a TK
	 * application is killed with one of these signals.
	 */

	signal(SIGINT, TkMacOSXSignalHandler);
	signal(SIGHUP, TkMacOSXSignalHandler);
	signal(SIGTERM, TkMacOSXSignalHandler);
    }

    /*
     * Initialization steps that are needed for all interpreters.
     */

    if (tkLibPath[0] != '\0') {
	Tcl_SetVar2(interp, "tk_library", NULL, tkLibPath, TCL_GLOBAL_ONLY);
    }

    if (scriptPath[0] != '\0') {
	Tcl_SetVar2(interp, "auto_path", NULL, scriptPath,
		TCL_GLOBAL_ONLY|TCL_LIST_ELEMENT|TCL_APPEND_VALUE);
    }

    Tcl_CreateObjCommand(interp, "::tk::mac::standardAboutPanel",
	    TkMacOSXStandardAboutPanelObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "::tk::mac::iconBitmap",
	    TkMacOSXIconBitmapObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "::tk::mac::GetAppPath",
	    TkMacOSXGetAppPathCmd, NULL, NULL);
    MacSystrayInit(interp);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetAppName --
486
487
488
489
490
491
492
493

494
495
496
497
498
499
500
501
502
503
504
505
506
621
622
623
624
625
626
627

628
629
630
631
632


633
634
635
636
637
638
639







-
+




-
-







 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TkMacOSXGetAppPathCmd(
    ClientData dummy,
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    (void)dummy;

    if (objc != 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }

    /*
     * Get the application path URL and convert it to a string path reference.
621
622
623
624
625
626
627
628
629


630
631
632
633
634
635
636
637
638
639
754
755
756
757
758
759
760


761
762
763
764

765
766
767
768
769
770
771







-
-
+
+


-







 *	None.
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE void*
TkMacOSXGetNamedSymbol(
    const char* module,
    const char* symbol)
    TCL_UNUSED(const char *),
    const char *symbol)
{
    void *addr = dlsym(RTLD_NEXT, symbol);
    (void)module;

    if (!addr) {
	(void) dlerror(); /* Clear dlfcn error state */
    }
    return addr;
}


Changes to macosx/tkMacOSXInt.h.

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







+

+








/*
 * Include platform specific public interfaces.
 */

#ifndef _TKMAC
#include "tkMacOSX.h"
#define Cursor QDCursor
#import <Cocoa/Cocoa.h>
#undef Cursor
#endif

/*
 * Define compatibility platform types used in the structures below so that
 * this header can be included without pulling in the platform headers.
 */

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
96
97
98
99
100
101
102

































103
104
105
106
107
108
109







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







 * This is defined in tk.h. We need to duplicate the TK_EMBEDDED flag in the
 * TkWindow structure for the window, but in the MacWin. This way we can
 * still tell what the correct port is after the TKWindow structure has been
 * freed. This actually happens when you bind destroy of a toplevel to
 * Destroy of a child.
 */

/*
 * This structure is for handling Netscape-type in process
 * embedding where Tk does not control the top-level. It contains
 * various functions that are needed by Mac specific routines, like
 * TkMacOSXGetDrawablePort. The definitions of the function types
 * are in tkMacOSX.h.
 */

typedef struct {
    Tk_MacOSXEmbedRegisterWinProc *registerWinProc;
    Tk_MacOSXEmbedGetGrafPortProc *getPortProc;
    Tk_MacOSXEmbedMakeContainerExistProc *containerExistProc;
    Tk_MacOSXEmbedGetClipProc *getClipProc;
    Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc;
} TkMacOSXEmbedHandler;

MODULE_SCOPE TkMacOSXEmbedHandler *tkMacOSXEmbedHandler;

/*
 * GC CGColorRef cache for tkMacOSXColor.c
 */

typedef struct {
    unsigned long cachedForeground;
    CGColorRef cachedForegroundColor;
    unsigned long cachedBackground;
    CGColorRef cachedBackgroundColor;
} TkpGCCache;

MODULE_SCOPE TkpGCCache *TkpGetGCCache(GC gc);
MODULE_SCOPE void TkpInitGCCache(GC gc);
MODULE_SCOPE void TkpFreeGCCache(GC gc);

/*
 * Undef compatibility platform types defined above.
 */

#ifndef _TKMACPRIV
#   ifndef CGGEOMETRY_H_
#	ifndef CGFLOAT_DEFINED
176
177
178
179
180
181
182
183

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

200
201
202
203
204
205
206
207
145
146
147
148
149
150
151

152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167

168

169
170
171
172
173
174
175







-
+















-
+
-








#define TK_LOCATION_CHANGED	1
#define TK_SIZE_CHANGED		2
#define TK_BOTH_CHANGED		3
#define TK_MACOSX_HANDLE_EVENT_IMMEDIATELY 1024

/*
 * Defines for tkTextDisp.c
 * Defines for tkTextDisp.c and tkFont.c
 */

#define TK_LAYOUT_WITH_BASE_CHUNKS	1
#define TK_DRAW_IN_CONTEXT		1

/*
 * Prototypes of internal procs not in the stubs table.
 */

MODULE_SCOPE void TkMacOSXDefaultStartupScript(void);
MODULE_SCOPE void TkpClipDrawableToRect(Display *display, Drawable d, int x,
	int y, int width, int height);
MODULE_SCOPE void TkpRetainRegion(Region r);
MODULE_SCOPE void TkpReleaseRegion(Region r);
MODULE_SCOPE void TkpShiftButton(NSButton *button, NSPoint delta);
MODULE_SCOPE Bool TkTestLogDisplay(void);
MODULE_SCOPE Bool TkTestLogDisplay(Drawable drawable);
MODULE_SCOPE Bool TkMacOSXInDarkMode(Tk_Window tkwin);

/*
 * 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 <[email protected]>
 * Copyright (c) 2012 Adrian Robert.
 * Copyright 2015-2020 Marc Culler.
 * Copyright © 2001-2009, Apple Inc.
 * Copyright © 2006-2009 Daniel A. Steffen <[email protected]>
 * 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"
47
48
49
50
51
52
53
54

55
56
57
58
59
60
61
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61







-
+







- (NSEvent *) tkProcessKeyEvent: (NSEvent *) theEvent
{
#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif
    NSWindow *w = [theEvent window];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w), *grabWinPtr, *focusWinPtr;
    Tk_Window tkwin = (Tk_Window) winPtr;
    Tk_Window tkwin = (Tk_Window)winPtr;
    NSEventType type = [theEvent type];
    NSUInteger virtual = [theEvent keyCode];
    NSUInteger modifiers = ([theEvent modifierFlags] &
			    NSDeviceIndependentModifierFlagsMask);
    XEvent xEvent;
    MacKeycode macKC;
    UniChar keychar = 0;
79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
79
80
81
82
83
84
85

86
87
88
89
90
91
92
93







-
+







     */

    grabWinPtr = winPtr->dispPtr->grabWinPtr;
    if (grabWinPtr) {
	if (winPtr->dispPtr->grabFlags ||  /* global grab */
	    grabWinPtr->mainPtr == winPtr->mainPtr){ /* same application */
	    winPtr =winPtr->dispPtr->focusPtr;
	    tkwin = (Tk_Window) winPtr;
	    tkwin = (Tk_Window)winPtr;
	}
    }

    /*
     * Extract the unicode character from KeyUp and KeyDown events.
     */

251
252
253
254
255
256
257

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

272
273
274
275

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

297
298
299
300
301
302
303
251
252
253
254
255
256
257
258
259
260
261
262


263
264
265
266
267
268
269

270




271



272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288

289
290
291
292
293
294
295
296







+




-
-







-
+
-
-
-
-
+
-
-
-

















-
+








    /*
     * 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;
    }
    if (xEvent.xany.type == KeyPress) {
    }
    Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
    return theEvent;
}
@end


@implementation TKContentView

@synthesize tkDirtyRect = _tkDirtyRect;
-(id)init {
    self = [super init];
    if (self) {
        _needsRedisplay = NO;
@synthesize tkNeedsDisplay = _tkNeedsDisplay;
    }
    return self;
}

/*
 * Implementation of the NSTextInputClient protocol.
 */

/* [NSTextInputClient inputText: replacementRange:] is called by
 * interpretKeyEvents when a composition sequence is complete.  It is also
 * called when we delete working text.  In that case the call is followed
 * immediately by doCommandBySelector: deleteBackward:
 */
- (void)insertText: (id)aString
  replacementRange: (NSRange)repRange
{
    int i, len, state;
    XEvent xEvent;
    NSString *str, *keystr, *lower;
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
    Tk_Window tkwin = (Tk_Window) winPtr;
    Tk_Window tkwin = (Tk_Window)winPtr;
    Bool sendingIMEText = NO;

    str = ([aString isKindOfClass: [NSAttributedString class]]) ?
        [aString string] : aString;
    len = [str length];

    if (NS_KEYLOG) {
325
326
327
328
329
330
331
332
333


334
335
336
337
338
339
340
318
319
320
321
322
323
324


325
326
327
328
329
330
331
332
333







-
-
+
+







     * Apple evidently sets location to 0 to signal that an accented letter has
     * been selected from the accent menu.  An unaccented letter has already
     * been displayed and we need to erase it before displaying the accented
     * letter.
     */

    if (repRange.location == 0) {
	Tk_Window focusWin = (Tk_Window) winPtr->dispPtr->focusPtr;
	TkSendVirtualEvent(focusWin, "TkAccentBackspace", NULL);
	Tk_Window focusWin = (Tk_Window)winPtr->dispPtr->focusPtr;
	Tk_SendVirtualEvent(focusWin, "TkAccentBackspace", NULL);
    }

    /*
     * Next we generate an XEvent for each unicode character in our string.
     * This string could contain non-BMP characters, for example if the
     * emoji palette was used.
     *
399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
392
393
394
395
396
397
398

399
400
401
402
403
404
405
406







-
+







 */

- (void)setMarkedText: (id)aString
	selectedRange: (NSRange)selRange
     replacementRange: (NSRange)repRange
{
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
    Tk_Window focusWin = (Tk_Window) winPtr->dispPtr->focusPtr;
    Tk_Window focusWin = (Tk_Window)winPtr->dispPtr->focusPtr;
    NSString *temp;
    NSString *str;
    (void)selRange;

    str = ([aString isKindOfClass: [NSAttributedString class]]) ?
        [aString string] : aString;
    if (focusWin) {
435
436
437
438
439
440
441
442

443
444
445
446
447

448
449
450
451
452
453
454
428
429
430
431
432
433
434

435
436
437
438
439

440
441
442
443
444
445
446
447







-
+




-
+







	return;
    }

    /*
     * Use our insertText method to display the marked text.
     */

    TkSendVirtualEvent(focusWin, "TkStartIMEMarkedText", NULL);
    Tk_SendVirtualEvent(focusWin, "TkStartIMEMarkedText", NULL);
    processingCompose = YES;
    temp = [str copy];
    [self insertText: temp replacementRange:repRange];
    privateWorkingText = temp;
    TkSendVirtualEvent(focusWin, "TkEndIMEMarkedText", NULL);
    Tk_SendVirtualEvent(focusWin, "TkEndIMEMarkedText", NULL);
}

- (BOOL)hasMarkedText
{
    return privateWorkingText != nil;
}

508
509
510
511
512
513
514
515
516


517
518
519
520
521
522
523
501
502
503
504
505
506
507


508
509
510
511
512
513
514
515
516







-
-
+
+







{
    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;
	TkSendVirtualEvent(focusWin, "TkAccentBackspace", NULL);
	Tk_Window focusWin = (Tk_Window)winPtr->dispPtr->focusPtr;
	Tk_SendVirtualEvent(focusWin, "TkAccentBackspace", NULL);
    }
}

- (NSArray *)validAttributesForMarkedText
{
    static NSArray *arr = nil;
    if (arr == nil) {
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
551
552
553
554
555
556
557

558
559
560
561
562
563
564







-







    if (NS_KEYLOG) {
	TKLog(@"attributedSubstringFromRange request");
    }
    return str;
}
/* End of NSTextInputClient implementation. */

@synthesize needsRedisplay = _needsRedisplay;
@end


@implementation TKContentView(TKKeyEvent)

/*
 * Tell the widget to erase the displayed composing characters.  This
584
585
586
587
588
589
590
591

592
593
594
595
596
597
598
576
577
578
579
580
581
582

583
584
585
586
587
588
589
590







-
+







		  (unsigned long)[privateWorkingText length]);
	}

	[privateWorkingText release];
	privateWorkingText = nil;
	processingCompose = NO;
	if (composeWin) {
	    TkSendVirtualEvent(composeWin, "TkClearIMEMarkedText", NULL);
	    Tk_SendVirtualEvent(composeWin, "TkClearIMEMarkedText", NULL);
	}
    }
}

- (void)cancelComposingText
{
    if (NS_KEYLOG) {
705
706
707
708
709
710
711
712
713


714
715
716
717
718
719
720
697
698
699
700
701
702
703


704
705
706
707
708
709
710
711
712







-
-
+
+







    TkWindow *captureWinPtr = (TkWindow *) TkpGetCapture();
    (void)owner_events;
    (void)pointer_mode;
    (void)keyboard_mode;
    (void)time;

    if (keyboardGrabWinPtr && captureWinPtr) {
	NSWindow *w = TkMacOSXDrawableWindow(grab_window);
	MacDrawable *macWin = (MacDrawable *) grab_window;
	NSWindow *w = TkMacOSXGetNSWindowForDrawable(grab_window);
	MacDrawable *macWin = (MacDrawable *)grab_window;

	if (w && macWin->toplevel->winPtr == (TkWindow *) captureWinPtr) {
	    if (modalSession) {
		Tcl_Panic("XGrabKeyboard: already grabbed");
	    }
	    keyboardGrabNSWindow = w;
	    [w retain];
784
785
786
787
788
789
790
791

792
793
794
795
796
797
798
776
777
778
779
780
781
782

783
784
785
786
787
788
789
790







-
+







 *----------------------------------------------------------------------
 *
 * Tk_SetCaretPos --
 *
 *	This enables correct placement of the popups used for character
 *      selection by the NSTextInputClient.  It gets called by text entry
 *      widgets whenever the cursor is drawn.  It does nothing if the widget's
 *      NSWindow is not the current KeyWindow.  Otherwise it udpates the
 *      NSWindow is not the current KeyWindow.  Otherwise it updates the
 *      display's caret structure and records the caret geometry in static
 *      variables for use by the NSTextInputClient implementation.  Any
 *      widget passed to this function will be marked as being able to input
 *      text by setting the TK_CAN_INPUT_TEXT flag.
 *
 * Results:
 *	None
810
811
812
813
814
815
816
817

818
819
820
821
822
823
824
802
803
804
805
806
807
808

809
810
811
812
813
814
815
816







-
+







    Tk_Window tkwin,
    int x,
    int y,
    int height)
 {
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkCaret *caretPtr = &(winPtr->dispPtr->caret);
    NSWindow *w = TkMacOSXDrawableWindow(Tk_WindowId(tkwin));
    NSWindow *w = TkMacOSXGetNSWindowForDrawable(Tk_WindowId(tkwin));

    /*
     * Register this widget as being capable of text input, so we know we
     * should process (appropriate) key events for this window with the
     * NSTextInputClient protocol.
     */

Changes to macosx/tkMacOSXKeyboard.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





-
-
-
-
+
+
+
+







/*
 * 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 <[email protected]>
 * Copyright (c) 2020 Marc Culler
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009, Apple Inc.
 * Copyright © 2005-2009 Daniel A. Steffen <[email protected]>
 * 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"
485
486
487
488
489
490
491
492

493
494
495
496
497
498
499
500
501
502
503
504
505
485
486
487
488
489
490
491

492
493
494
495
496
497

498
499
500
501
502
503
504







-
+





-







 *	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. */
{
    (void) winPtr; /*unused*/
    MacKeycode macKC;
    char utfChars[8];
    int length = 0;

    macKC.uint = eventPtr->xkey.keycode;
    if (IS_PRINTABLE(macKC.v.keychar)) {
	length = TkUniCharToUtf(macKC.v.keychar, utfChars);
584
585
586
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







-
+

-
-





-
+

-
-







 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
XKeysymToString(
    KeySym keysym)
    TCL_UNUSED(KeySym))
{
    (void)keysym;

    return NULL;
}

KeySym
XStringToKeysym(
    const char* string)
    TCL_UNUSED(const char *))
{
    (void)string;

    return NoSymbol;
}

/*
 *----------------------------------------------------------------------
 *
 * XKeysymToKeycode --
662
663
664
665
666
667
668
669

670
671
672
673
674
675
676
657
658
659
660
661
662
663

664
665
666
667
668
669
670
671







-
+







    hPtr = (Tcl_HashEntry *) Tcl_FindHashEntry(&keysym2unichar,
					       INT2PTR(keysym));
    if (hPtr != NULL) {
	unsigned long data = (unsigned long) Tcl_GetHashValue(hPtr);
	macKC.x.keychar = (unsigned int) data;
	hPtr = Tcl_FindHashEntry(&unichar2xvirtual, INT2PTR(macKC.x.keychar));
	if (hPtr != NULL) {
	    unsigned long data = (unsigned long) Tcl_GetHashValue(hPtr);
	    data = (unsigned long) Tcl_GetHashValue(hPtr);
	    macKC.x.xvirtual = (unsigned int) data;
	}
    }
    return (KeyCode) macKC.uint;
}

/*

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 <[email protected]>
 * 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 <[email protected]>
 * 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
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







-
+







    {109,	XK_F10,		NSF10FunctionKey},
    {110,       XK_Menu,	UNKNOWN_KEYCHAR},
    {111,	XK_F12,		NSF12FunctionKey},
    {113,	XK_F15,		NSF15FunctionKey},
    {114,	XK_Help,	NSHelpFunctionKey},
    {115,	XK_Home,	NSHomeFunctionKey},     /* Fn Left */
    {116,	XK_Page_Up,	NSPageUpFunctionKey},   /* Fn Up */
    {117,	XK_Delete,	NSDeleteFunctionKey},   /* Fn Deleete */
    {117,	XK_Delete,	NSDeleteFunctionKey},   /* Fn Delete */
    {118,	XK_F4,		NSF4FunctionKey},
    {119,	XK_End,		NSEndFunctionKey},      /* Fn Right */
    {120,	XK_F2,		NSF2FunctionKey},
    {121,	XK_Page_Down,	NSPageDownFunctionKey}, /* Fn Down */
    {122,	XK_F1,		NSF1FunctionKey},
    {123,	XK_Left,	NSLeftArrowFunctionKey},
    {124,	XK_Right,	NSRightArrowFunctionKey},

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 <[email protected]>
 * Copyright (c) 2012 Adrian Robert.
 * Copyright © 1996-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2005-2009 Daniel A. Steffen <[email protected]>
 * 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"
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48
49
50
51


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

68
69
70
71
72
73
74
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46
47
48
49


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

67
68
69
70
71
72
73
74







-
+










-
-
+
+















-
+







#define ENTRY_WINDOWS_MENU	ENTRY_PLATFORM_FLAG3

#define sl(s) ((int) (sizeof(s "") - 1))

#define SPECIALMENU(n, f) {.name = "." #n, .len = sl(#n) + 1, \
	.flag = ENTRY_##f##_MENU }
static const struct {
    const char *name; const size_t len; const int flag;
    const char *name; size_t len; int flag;
} specialMenus[] = {
    SPECIALMENU(help,	HELP),
    SPECIALMENU(apple,	APPLE),
    SPECIALMENU(window,	WINDOWS),
    {NULL, 0, 0}
};
#undef SPECIALMENU

#define MODIFIER(n, f) {.name = #n, .len = sl(#n), .mask = f }
static const struct {
    const char *name; const size_t len; const NSUInteger mask;
} modifiers[] = {
    const char *name; size_t len; NSUInteger mask;
} allModifiers[] = {
    MODIFIER(Control,	NSControlKeyMask),
    MODIFIER(Ctrl,	NSControlKeyMask),
    MODIFIER(Option,	NSAlternateKeyMask),
    MODIFIER(Opt,	NSAlternateKeyMask),
    MODIFIER(Alt,	NSAlternateKeyMask),
    MODIFIER(Shift,	NSShiftKeyMask),
    MODIFIER(Command,	NSCommandKeyMask),
    MODIFIER(Cmd,	NSCommandKeyMask),
    MODIFIER(Meta,	NSCommandKeyMask),
    {NULL, 0, 0}
};
#undef MODIFIER

#define ACCEL(n, c) {.name = #n, .len = sl(#n), .ch = c }
static const struct {
    const char *name; const size_t len; const UniChar ch;
    const char *name; size_t len; UniChar ch;
} specialAccelerators[] = {
    ACCEL(PageUp,	NSPageUpFunctionKey),
    ACCEL(PageDown,	NSPageDownFunctionKey),
    ACCEL(Left,		NSLeftArrowFunctionKey),
    ACCEL(Right,	NSRightArrowFunctionKey),
    ACCEL(Up,		NSUpArrowFunctionKey),
    ACCEL(Down,		NSDownArrowFunctionKey),
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109





























































110
111
112
113
114
115
116
87
88
89
90
91
92
93



94

95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173







-
-
-

-











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







    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 unsigned long defaultBg = 0, defaultFg = 0;
static SInt32 menuMarkColumnWidth = 0, menuIconTrailingEdgeMargin = 0;
static SInt32 menuTextLeadingEdgeMargin = 0, menuTextTrailingEdgeMargin = 0;
static SInt16 menuItemExtraHeight = 0, menuItemExtraWidth = 0;
static SInt16 menuSeparatorHeight = 0;

static void	CheckForSpecialMenu(TkMenu *menuPtr);
static NSString *ParseAccelerator(const char *accel, NSUInteger *maskPtr);
static int	GenerateMenuSelectEvent(TKMenu *menu, NSMenuItem *menuItem);
static void	MenuSelectEvent(TkMenu *menuPtr);
static void	RecursivelyClearActiveMenu(TkMenu *menuPtr);
static int	ModifierCharWidth(Tk_Font tkfont);

#pragma mark TkBackgroundLoop

/*
 * The function TkMacOSXEventsCheckProc (in tkMacOSXNotify.c) is the "check
 * proc" for the macOS event source.  Its job is to remove NSEvents from the
 * default event queue of the NSApplication.  It does this by calling the
 * method [NSApp nextEventMatchingMask: untilDate: inMode: dequeue:]. As a
 * rule, when the untilDate is set to the distant past this method returns
 * immediately.  An exception to that rule is when the next event is the button
 * press on a menu button.  In that case, the method starts running a nested
 * event loop in the mode NSEventTrackingRunLoopMode which does not return
 * until the menu has been dismissed.  In Tk 8.6.10 and earlier, this meant
 * that the Tk event loop would block in its call to the check proc as long as
 * the menu was posted.  For example, opening a menu during the Rube Goldberg
 * demo would cause the animation to stop.  This was also the case for
 * menubuttons.
 *
 * The TKBackground object below works around this problem, and allows a Tk
 * event loop to run while a menu is open.  It is a subclass of NSThread which
 * inserts requests to call [NSApp _runBackgroundLoop] onto the queue
 * associated with the NSEventTrackingRunLoopMode.  One of these threads gets
 * started in the callback [NSApp menuBeginTracking] and cancelled in [NSApp
 * menuEndTracking].
 */

@interface TKBackgroundLoop: NSThread
@end

@implementation TKBackgroundLoop
- (void) main
{
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    NSArray *modeArray = [NSArray arrayWithObjects: NSEventTrackingRunLoopMode,
				  nil];
    while(1) {

	/*
	 * Queue a request to process Tk events during event tracking.
	 */

	[NSApp performSelectorOnMainThread:@selector(_runBackgroundLoop)
				withObject:nil
			     waitUntilDone:true
				     modes:modeArray];
	if ([self isCancelled]) {
	    [NSThread exit];
	}

	/*
	 * Allow the tracked events to be processed too.
	 */

	[NSThread sleepForTimeInterval:0.001];
    }
    [pool drain];
}
@end

TKBackgroundLoop *backgroundLoop = nil;


#pragma mark TKMenu

/*
 * This interface is not declared in tkMacOSXPrivate.h because it requires
 * tkMenu.h.
 */
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
312
313
314
315
316
317
318






319
320
321
322
323
324
325







-
-
-
-
-
-







	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) {
401
402
403
404
405
406
407






408
409
410
411
412
413
414
415
416
417





418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486




487
488
489
490
491
492
493







+
+
+
+
+
+










+
+
+
+
+







-
-
-
-








- (void) menuBeginTracking: (NSNotification *) notification
{
    (void)notification;
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    if (backgroundLoop) {
	[backgroundLoop cancel];
	[backgroundLoop release];
    }
    backgroundLoop = [[TKBackgroundLoop alloc] init];
    [backgroundLoop start];
    //TkMacOSXClearMenubarActive();
    //TkMacOSXPreprocessMenu();
}

- (void) menuEndTracking: (NSNotification *) notification
{
    (void)notification;
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    if (backgroundLoop) {
	[backgroundLoop cancel];
	[backgroundLoop release];
	backgroundLoop = nil;
    }
    if (!inPostMenu) {
	TkMacOSXClearMenubarActive();
    }
}

- (void) tkSetMainMenu: (TKMenu *) menu
{
    if (gNoTkMenus) {
	return;
    }

    TKMenu *applicationMenu = nil;

    if (menu) {
	NSMenuItem *applicationMenuItem = [menu numberOfItems] ?
		[menu itemAtIndex:0] : nil;

	if (![menu isSpecial:tkMainMenu]) {
617
618
619
620
621
622
623
624
625
626
627
628













629
630
631
632

633
634
635
636
637
638
639
640

641
642
643
644

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
675
676
677
678
679
680
681

682
683


684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699

700
701
702
703
704
705
706
707

708
709



710

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








724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750






751
752
753
754
755
756
757
758



759
760
761
762
763
764
765
766

767
768
769
770
771
772
773
774







-


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



-
+







-
+

-
-
-
+
-













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

-
+







    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 = TkMacOSXGetNSImageWithTkImage(mePtr->menuPtr->display,
	image = TkMacOSXGetNSImageFromTkImage(mePtr->menuPtr->display,
		mePtr->image, imageWidth, imageHeight);
    } else if (mePtr->bitmapPtr != None) {
	Pixmap bitmap = Tk_GetBitmapFromObj(mePtr->menuPtr->tkwin,
		mePtr->bitmapPtr);

	Tk_SizeOfBitmap(mePtr->menuPtr->display, bitmap, &imageWidth,
		&imageHeight);
	image = TkMacOSXGetNSImageWithBitmap(mePtr->menuPtr->display, bitmap,
	image = TkMacOSXGetNSImageFromBitmap(mePtr->menuPtr->display, bitmap,
		gc, imageWidth, imageHeight);
	if (gc->foreground == defaultFg) {
	    // Use a semantic foreground color by default
	    [image setTemplate:YES];
	[image setTemplate:YES];
	}
    }
    [menuItem setImage:image];
    if ((!image || mePtr->compound != COMPOUND_NONE) && mePtr->labelPtr &&
	    mePtr->labelLength) {
	title = [[[NSString alloc] initWithBytes:Tcl_GetString(mePtr->labelPtr)
		length:mePtr->labelLength encoding:NSUTF8StringEncoding]
		autorelease];
	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];
    [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);
    }
703
704
705
706
707
708
709
710
711
712





713
714
715
716
717

718
719
720

721
722
723
724
725
726
727
728
729

730
731
732
733
734
735
736
737
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







-
-
-
+
+
+
+
+


-
-
-
+
-

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







		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 (TkSizeT 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];

816
817
818
819
820
821
822
823

824
825
826
827
828
829
830
896
897
898
899
900
901
902

903
904
905
906
907
908
909
910







-
+







	 * Fix for bug 07cfc9f03e: use the view for the parent real (non-menu)
	 * toplevel window, rather than always using the root window.
	 * This allows menus to appear on a separate monitor than the root
	 * window, and to use the appearance of their parent real window
	 * rather than the appearance of the root window.
	 */
	realWinPtr = (TkWindow*) realWin;
	realWinView = TkMacOSXDrawableView(realWinPtr->privatePtr);
	realWinView = TkMacOSXGetNSViewForDrawable(realWinPtr->privatePtr);
	if (realWinView != nil) {
	    break;
	}
	realWin = Tk_Parent(realWin);
    }
    NSWindow *win = [realWinView window];
    NSView *view = [win contentView];
1037
1038
1039
1040
1041
1042
1043
1044
1045


1046
1047
1048
1049
1050
1051
1052
1117
1118
1119
1120
1121
1122
1123


1124
1125
1126
1127
1128
1129
1130
1131
1132







-
-
+
+







    }

    if (menuName) {
	Tk_Window menubar = NULL;

	if (winPtr->wmInfoPtr &&
		winPtr->wmInfoPtr->menuPtr &&
		winPtr->wmInfoPtr->menuPtr->masterMenuPtr) {
	    menubar = winPtr->wmInfoPtr->menuPtr->masterMenuPtr->tkwin;
		winPtr->wmInfoPtr->menuPtr->mainMenuPtr) {
	    menubar = winPtr->wmInfoPtr->menuPtr->mainMenuPtr->tkwin;
	}

	/*
	 * Attempt to find the NSMenu directly.  If that fails, ask Tk to find
	 * it.
	 */

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







-
+






-
-
+
+




-
+




-
+







 *----------------------------------------------------------------------
 */

static void
CheckForSpecialMenu(
    TkMenu *menuPtr)		/* The menu we are checking */
{
    if (!menuPtr->masterMenuPtr->tkwin) {
    if (!menuPtr->mainMenuPtr->tkwin) {
	return;
    }
    for (TkMenuEntry *cascadeEntryPtr = menuPtr->menuRefPtr->parentEntryPtr;
	    cascadeEntryPtr;
	    cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) {
	if (cascadeEntryPtr->menuPtr->menuType == MENUBAR
		&& cascadeEntryPtr->menuPtr->masterMenuPtr->tkwin) {
	    TkMenu *masterMenuPtr = cascadeEntryPtr->menuPtr->masterMenuPtr;
		&& cascadeEntryPtr->menuPtr->mainMenuPtr->tkwin) {
	    TkMenu *mainMenuPtr = cascadeEntryPtr->menuPtr->mainMenuPtr;
	    int i = 0;
	    Tcl_DString ds;

	    Tcl_DStringInit(&ds);
	    Tcl_DStringAppend(&ds, Tk_PathName(masterMenuPtr->tkwin), -1);
	    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->masterMenuPtr->tkwin)) == 0) {
			Tk_PathName(menuPtr->mainMenuPtr->tkwin)) == 0) {
		    cascadeEntryPtr->entryFlags |= specialMenus[i].flag;
		} else {
		    cascadeEntryPtr->entryFlags &= ~specialMenus[i].flag;
		}
		Tcl_DStringSetLength(&ds, Tcl_DStringLength(&ds) -
			specialMenus[i].len);
		i++;
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
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







-
-
+
+

-
+

-
+





-
+







    unichar ch = 0;
    size_t len;
    int i;

    *maskPtr = 0;
    while (1) {
	i = 0;
	while (modifiers[i].name) {
	    int l = modifiers[i].len;
	while (allModifiers[i].name) {
	    int l = allModifiers[i].len;

	    if (!strncasecmp(accel, modifiers[i].name, l) &&
	    if (!strncasecmp(accel, allModifiers[i].name, l) &&
		    (accel[l] == '-' || accel[l] == '+')) {
		*maskPtr |= modifiers[i].mask;
		*maskPtr |= allModifiers[i].mask;
		accel += l+1;
		break;
	    }
	    i++;
	}
	if (!modifiers[i].name || !*accel) {
	if (!allModifiers[i].name || !*accel) {
	    break;
	}
    }
    len = strlen(accel);
    if (len > 1) {
	i = 0;
	if (accel[0] == 'F' && len < 4 && accel[1] > '0' && accel[1] <= '9') {
1269
1270
1271
1272
1273
1274
1275
1276

1277
1278
1279
1280
1281
1282
1283
1349
1350
1351
1352
1353
1354
1355

1356
1357
1358
1359
1360
1361
1362
1363







-
+







    TkMenuEntry *mePtr;
    int haveAccel = 0;

    /*
     * Do nothing if this menu is a clone.
     */

    if (menuPtr->tkwin == NULL || menuPtr->masterMenuPtr != menuPtr) {
    if (menuPtr->tkwin == NULL || menuPtr->mainMenuPtr != menuPtr) {
	return;
    }

    menuSize = [(NSMenu *) menuPtr->platformData size];
    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
	    &borderWidth);
    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr,
1387
1388
1389
1390
1391
1392
1393
1394

1395
1396
1397
1398



1399
1400
1401

1402
1403
1404
1405
1406
1407
1408
1467
1468
1469
1470
1471
1472
1473

1474
1475



1476
1477
1478
1479
1480

1481
1482
1483
1484
1485
1486
1487
1488







-
+

-
-
-
+
+
+


-
+







		modifierWidth = modifierCharWidth;
	    } else if (mePtr->accelLength == 0) {
		if (haveAccel && !mePtr->hideMargin) {
		    modifierWidth = modifierCharWidth;
		}
	    } else {
		NSUInteger modifMask = [menuItem keyEquivalentModifierMask];
		int i = 0;
		int j = 0;

		while (modifiers[i].name) {
		    if (modifMask & modifiers[i].mask) {
			modifMask &= ~modifiers[i].mask;
		while (allModifiers[j].name) {
		    if (modifMask & allModifiers[j].mask) {
			modifMask &= ~allModifiers[j].mask;
			modifierWidth += modifierCharWidth;
		    }
		    i++;
		    j++;
		}
		accelWidth = [[menuItem keyEquivalent] sizeWithAttributes:
			TkMacOSXNSFontAttributesForFont(tkfont)].width;
	    }
	    if (!mePtr->hideMargin) {
		indicatorSpace = menuMarkColumnWidth;
	    }
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
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







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
















-
-









-
-
-
-
-
-
-







	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MacOSXTurnOffMenus --
 *
 *	Turns off all the menu drawing code. This is more than just disabling
 *	the "menu" command, this means that Tk will NEVER touch the menubar.
 *	It is needed in the Plugin, where Tk does not own the menubar.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A flag is set which will disable all menu drawing.
 *
 *----------------------------------------------------------------------
 */

void
Tk_MacOSXTurnOffMenus(void)
{
    gNoTkMenus = 1;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpMenuInit --
 *
 *	Initializes Mac-specific menu data.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Allocates a hash table.
 *
 *----------------------------------------------------------------------
 */

void
TkpMenuInit(void)
{
    TkColor *tkColPtr;

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

#define observe(n, s) \
	[nc addObserver:NSApp selector:@selector(s) name:(n) object:nil]
    observe(NSMenuDidBeginTrackingNotification, menuBeginTracking:);
    observe(NSMenuDidEndTrackingNotification, menuEndTracking:);
#undef observe

    [NSMenuItem setUsesUserKeyEquivalents:NO];
    tkColPtr = TkpGetColor(NULL, DEF_MENU_BG_COLOR);
    defaultBg = tkColPtr->color.pixel;
    ckfree(tkColPtr);
    tkColPtr = TkpGetColor(NULL, DEF_MENU_FG);
    defaultFg = tkColPtr->color.pixel;
    ckfree(tkColPtr);

    ChkErr(GetThemeMetric, kThemeMetricMenuMarkColumnWidth,
	    &menuMarkColumnWidth);
    ChkErr(GetThemeMetric, kThemeMetricMenuTextLeadingEdgeMargin,
	    &menuTextLeadingEdgeMargin);
    ChkErr(GetThemeMetric, kThemeMetricMenuTextTrailingEdgeMargin,
	    &menuTextTrailingEdgeMargin);
    ChkErr(GetThemeMetric, kThemeMetricMenuIconTrailingEdgeMargin,
1768
1769
1770
1771
1772
1773
1774
1775





1776
1777
1778
1779
1780
1781

1782
1783
1784
1785
1786
1787
1788
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







-
+
+
+
+
+





-
+








/*
 *----------------------------------------------------------------------
 *
 * 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 <[email protected]>
 * 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 <[email protected]>
 * 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"
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
176
177
178
179
180
181
182







183
184
185
186
187
188
189







-
-
-
-
-
-
-







        return;
    }

    pixmap = (Pixmap) Tk_WindowId(tkwin);

    TkMacOSXComputeMenuButtonDrawParams(butPtr, dpPtr);

    /*
     * Set up clipping region.  Make sure the we are using the port for this
     * button, or we will set the wrong window's clip.
     */

    TkMacOSXSetUpClippingRgn(pixmap);

    /*
     * Draw the native portion of the buttons.
     */

    TkMacOSXDrawMenuButton(mbPtr,  dpPtr->gc, pixmap);

    /*
360
361
362
363
364
365
366
367

368
369
370
371
372
373
374
353
354
355
356
357
358
359

360
361
362
363
364
365
366
367







-
+







}

/*
 *----------------------------------------------------------------------
 *
 * DrawMenuButtonImageAndText --
 *
 *        Draws the image and text associated witha button or label.
 *        Draws the image and text associated with a button or label.
 *
 * Results:
 *        None.
 *
 * Side effects:
 *        The image and text are drawn.
 *
563
564
565
566
567
568
569
570

571
572
573
574
575
576
577
556
557
558
559
560
561
562

563
564
565
566
567
568
569
570







-
+







	    Tk_Width(butPtr->tkwin), Tk_Height(butPtr->tkwin));

    if (useNewerHITools == 1) {
        HIRect contHIRec;
        static HIThemeButtonDrawInfo hiinfo;

        MenuButtonBackgroundDrawCB(mbPtr, 32, true);
	if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, 1, &dc)) {
	if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, &dc)) {
	    return;
	}

        hiinfo.version = 0;
        hiinfo.state = mbPtr->drawinfo.state;
        hiinfo.kind = mbPtr->btnkind;
        hiinfo.value = mbPtr->drawinfo.value;
594
595
596
597
598
599
600
601

602
603
604
605
606
607
608
587
588
589
590
591
592
593

594
595
596
597
598
599
600
601







-
+








        HIThemeDrawButton(&cntrRect, &hiinfo, dc.context,
		kHIThemeOrientationNormal, &contHIRec);
	TkMacOSXRestoreDrawingContext(&dc);
        MenuButtonContentDrawCB(mbPtr->btnkind, &mbPtr->drawinfo,
		mbPtr, 32, true);
    } else {
	if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, 1, &dc)) {
	if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, &dc)) {
	    return;
	}
	TkMacOSXRestoreDrawingContext(&dc);
    }
    mbPtr->lastdrawinfo = mbPtr->drawinfo;
}

706
707
708
709
710
711
712
713

714
715
716
717
718
719
720
699
700
701
702
703
704
705

706
707
708
709
710
711
712
713







-
+







	}
	if (eventPtr->type == ActivateNotify) {
	    mbPtr->flags |= ACTIVE;
	} else {
	    mbPtr->flags &= ~ACTIVE;
	}
	if ((buttonPtr->flags & REDRAW_PENDING) == 0) {
	    Tcl_DoWhenIdle(TkpDisplayMenuButton, (ClientData) buttonPtr);
	    Tcl_DoWhenIdle(TkpDisplayMenuButton, buttonPtr);
	    buttonPtr->flags |= REDRAW_PENDING;
	}
    }
}

/*
 *----------------------------------------------------------------------

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 <[email protected]>
 * Copyright © 1995-1996 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2005-2009 Daniel A. Steffen <[email protected]>
 *
 * 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"
199
200
201
202
203
204
205
206

207
208
209
210
211
212
213
199
200
201
202
203
204
205

206
207
208
209
210
211
212
213







-
+








- (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);
	}
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
369
370
371
372
373
374
375























376
377
378
379
380
381
382







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







{
    Tcl_Panic("TkMacOSXHandleMenuSelect: Obsolete, no more Carbon!");
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXInitMenus --
 *
 *	This procedure initializes the Macintosh menu bar.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXInitMenus(
    TCL_UNUSED(Tcl_Interp *))
{
    [NSApp _setupMenus];
}

/*
 *----------------------------------------------------------------------
 *
 * GenerateEditEvent --
 *
 *	Takes an edit menu item and posts the corasponding a virtual event to
 *	Tk's event queue.
 *
 * Results:
 *	None.
418
419
420
421
422
423
424
425

426
427
428
429
430
431
432
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409







-
+







    int x, y;
    TkWindow *winPtr = TkMacOSXGetTkWindow([NSApp keyWindow]);
    Tk_Window tkwin;

    if (!winPtr) {
	return;
    }
    tkwin = (Tk_Window) winPtr->dispPtr->focusPtr;
    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;

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
1
2
3
4
5
6


7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

46


47
48
49
50
51
52
53
54
55
56
57
58

59
60

61





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



96
97
98
99
100
101
102
103
104

105
106
107
108
109
110
111
112
113

114
115
116
117
118

119

120
121
122
123
124
125

126
127

128
129
130
131
132



133
134
135
136
137


138
139
140
141



142
143
144
145


146
147
148



149




150
151
152
153
154
155


156




157
158
159




160
161
162
163
164
165
166
167







168
169
170
171
172
173
174





175
176
177
178



179
180
181





182
183
184
185
186





187


188



189
190
191
192
193

194
195
196
197

198
199
200
201
202
203
204


205
206
207
208
209
210







211


212


213









214



215


216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232



233
234
235
236
237
238




239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269

270




271
272
273
274
275
276
277






-
-
+
+


















+


















-
+
-
-
+
+







+
+

-
+

-
+
-
-
-
-
-
+
+
+
+




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

-
-
-
+
+
+
+



+
+
-
+
+

+
+
+
+
+

-
+
+
+
+

-
+
-

+
+
+


-
+

-
+




-
-
-
+
+
+


-
-
+
+
+

-
-
-
+
+
+
+
-
-
+
+

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

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

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

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



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


-
+



-
+



+


-
-
+
+
+
+


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
















-
-
-
+
+
+
+


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





-
+
-
-
-
-







/*
 * 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 <[email protected]>
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2005-2009 Daniel A. Steffen <[email protected]>
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXWm.h"
#include "tkMacOSXInt.h"
#include "tkMacOSXDebug.h"
#include "tkMacOSXConstants.h"

typedef struct {
    unsigned int state;
    long delta;
    Window window;
    Point global;
    Point local;
} MouseEventData;

static Tk_Window captureWinPtr = NULL;	/* Current capture window; may be
					 * NULL. */

static int		GenerateButtonEvent(MouseEventData *medPtr);
static unsigned int	ButtonModifiers2State(UInt32 buttonState,
			    UInt32 keyModifiers);

#pragma mark TKApplication(TKMouseEvent)

enum {
    NSWindowWillMoveEventType = 20
};

/*
 * In OS X 10.6 an NSEvent of type NSMouseMoved would always have a non-Nil
 * window attribute pointing to the active window.  As of 10.8 this behavior
 * had changed.  The new behavior was that if the mouse were ever moved outside
 * of a window, all subsequent NSMouseMoved NSEvents would have a Nil window
 * attribute.  To work around this the TKApplication remembers the last non-Nil
 * attribute until the mouse returned to the window.  In 11.1 it changed again.
 * window that it received in a mouse event. If it receives an NSEvent with a
 * Nil window attribute then the saved window is used.
 * The window attribute can be non-nil, but referencing a window which does not
 * belong to the application.
 */

@implementation TKApplication(TKMouseEvent)
- (NSEvent *) tkProcessMouseEvent: (NSEvent *) theEvent
{
    NSWindow *eventWindow = [theEvent window];
    NSEventType eventType = [theEvent type];
    NSRect viewFrame = [[eventWindow contentView] frame];
    NSPoint location = [theEvent locationInWindow];
    TkWindow *winPtr = NULL, *grabWinPtr;
    Tk_Window tkwin;
    Tk_Window tkwin = NULL, capture, target;
    NSPoint local, global;
    NSInteger button = -1;
    NSInteger button;
#if 0
    NSTrackingArea *trackingArea = nil;
    NSInteger eventNumber, clickCount, buttonNumber;
#endif
    [NSEvent stopPeriodicEvents];
    Bool inTitleBar = NO;
    int win_x, win_y;
    unsigned int buttonState = 0;
    static int validPresses = 0, ignoredPresses = 0;

#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif

    /*
     * If this event is not for a Tk toplevel, it should just be passed up the
     * responder chain.  However, there is an exception for synthesized events,
     * which are used in testing.  Those events are recognized by having their
     * both the windowNumber and the eventNumber set to -1.
     */

    if (eventWindow && ![eventWindow isMemberOfClass:[TKWindow class]]) {
	if ([theEvent windowNumber] != -1 || [theEvent eventNumber] != -1)
	    return theEvent;
    }

    /*
     * Check if the event is located in the titlebar.
     */

    if (eventWindow) {
	inTitleBar = viewFrame.size.height < location.y;
    }

    button = [theEvent buttonNumber] + Button1;
    if ((button & -2) == Button2) {
	button ^= 1; /* Swap buttons 2/3 */
    }
    switch (eventType) {
    case NSLeftMouseDown:
    case NSRightMouseDown:
    case NSOtherMouseDown:
    case NSRightMouseUp:
    case NSOtherMouseUp:
	buttonState &= ~Tk_GetButtonMask(button);
	break;
    case NSLeftMouseDragged:
    case NSRightMouseDragged:
    case NSOtherMouseDragged:
    case NSRightMouseDown:
    case NSOtherMouseDown:
	button = [theEvent buttonNumber] + Button1;
	buttonState |= Tk_GetButtonMask(button);
	break;
    case NSMouseEntered:
	if ([eventWindow respondsToSelector:@selector(mouseInResizeArea)] &&
	    !inTitleBar) {
	    [(TKWindow *)eventWindow setMouseInResizeArea:YES];
	}
	break;
    case NSMouseExited:
    case NSCursorUpdate:
	if ([eventWindow respondsToSelector:@selector(mouseInResizeArea)]) {
	    [(TKWindow *)eventWindow setMouseInResizeArea:NO];
	    break;
	}
    case NSLeftMouseUp:
    case NSRightMouseUp:
    case NSLeftMouseDown:
    case NSOtherMouseUp:
    case NSMouseMoved:
    case NSScrollWheel:
#if 0
    case NSCursorUpdate:
    case NSTabletPoint:
    case NSTabletProximity:
    case NSScrollWheel:
#endif
	break;
    default: /* Unrecognized mouse event. */
    default: /* This type of event is ignored. */
	return theEvent;
    }

    /*
     * Compute the mouse position in Tk screen coordinates (global) and in the
     * Tk coordinates of its containing Tk Window (local). If a grab is in effect,
     * the local coordinates should be relative to the grab window.
     * Update the button state.  We ignore left button presses that start a
     * resize or occur in the title bar.  See tickets [d72abe6b54] and
     * [39cbacb9e8].
     */

    if (eventWindow) {
	local = [theEvent locationInWindow];
    if (eventType == NSLeftMouseDown) {
	if ([eventWindow respondsToSelector:@selector(mouseInResizeArea)] &&
	    [(TKWindow *) eventWindow mouseInResizeArea]) {

	/*
	 * Do not send ButtonPress XEvents for MouseDown NSEvents that start a
	 * resize.  (The MouseUp will be handled during LiveResize.)  See
	    /*
	     * 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
	 * ticket [d72abe6b54].
	 */
	     * do not change the ignoredPresses count.
	     */

	if (eventType == NSLeftMouseDown &&
	    ([eventWindow styleMask] & NSResizableWindowMask) &&
	    [NSApp macOSVersion] > 100600) {
	    buttonState &= ~Tk_GetButtonMask(Button1);
	    NSRect frame = [eventWindow frame];
	    if (local.x < 3 || local.x > frame.size.width - 3 || local.y < 3) {
		return theEvent;
	    }
	    return theEvent;
	}
	if (inTitleBar) {
	    ignoredPresses++;
	    return theEvent;
	}
	global = [eventWindow tkConvertPointToScreen: local];
	tkwin = TkpGetCapture();
	validPresses++;
	if (tkwin) {
	    winPtr = (TkWindow *) tkwin;
	    eventWindow = TkMacOSXDrawableWindow(winPtr->window);
	    if (eventWindow) {
	buttonState |= Tk_GetButtonMask(Button1);
    }
    if (eventType == NSLeftMouseUp) {
		local = [eventWindow tkConvertPointFromScreen: global];
	    } else {
		return theEvent;
	    }
	if (ignoredPresses > 0) {
	    ignoredPresses--;
	} else if (validPresses > 0) {
	    validPresses--;
	}
	if (validPresses == 0) {
	    buttonState &= ~Tk_GetButtonMask(Button1);
	}
	local.y = [eventWindow frame].size.height - local.y;
	global.y = TkMacOSXZeroScreenHeight() - global.y;
    } else {

	/*
	 * If the event has no NSWindow, the location is in screen coordinates.
	 */
    }

    /*
     * Find an appropriate NSWindow to attach to this event, and its
     * associated Tk window.
     */

	global = [theEvent locationInWindow];
	tkwin = TkpGetCapture();
	if (tkwin) {
	    winPtr = (TkWindow *) tkwin;
	    eventWindow = TkMacOSXDrawableWindow(winPtr->window);
    capture = TkpGetCapture();
    if (capture) {
	winPtr = (TkWindow *) capture;
	eventWindow = TkMacOSXGetNSWindowForDrawable(winPtr->window);
	} else {
	    eventWindow = [NSApp mainWindow];
	}
	if (!eventWindow) {
	    return theEvent;
	}
	local = [eventWindow tkConvertPointFromScreen: global];
	local.y = [eventWindow frame].size.height - local.y;
	global.y = TkMacOSXZeroScreenHeight() - global.y;
    }

    } else {
	if (eventWindow) {
	    winPtr = TkMacOSXGetTkWindow(eventWindow);
	}
	if (!winPtr) {
    /*
     * If we still don't have a window, try using the toplevel that
     * manages the NSWindow.
     */

	    eventWindow = [NSApp mainWindow];
    if (!tkwin) {
	winPtr = TkMacOSXGetTkWindow(eventWindow);
	    winPtr = TkMacOSXGetTkWindow(eventWindow);
	tkwin = (Tk_Window) winPtr;
    }
    if (!tkwin) {
	}
    }
    if (!winPtr) {

	/*
	 * We can't find a window for this event.  We have to ignore it.
	 * We couldn't find a Tk window for this event.  We have to ignore it.
	 */

#ifdef TK_MAC_DEBUG_EVENTS
	TkMacOSXDbgMsg("tkwin == NULL");
	TkMacOSXDbgMsg("Event received with no Tk window.");
#endif
	return theEvent;
    }
    tkwin = (Tk_Window) winPtr;

    /*
     * Ignore the event if a local grab is in effect and the Tk event window is
     * not in the grabber's subtree.
     * Compute the mouse position in local (window) and global (screen)
     * coordinates.  These are Tk coordinates, meaning that the local origin is
     * at the top left corner of the containing toplevel and the global origin
     * is at top left corner of the primary screen.
     */

    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, tkEventWindow = Tk_CoordsToWindow(global.x, global.y, tkwin);
	if (!tkEventWindow) {
	    return theEvent;
    global = [NSEvent mouseLocation];
	}
	for (tkwin2 = tkEventWindow;
    local = [eventWindow tkConvertPointFromScreen: global];
	     !Tk_IsTopLevel(tkwin2);
	     tkwin2 = Tk_Parent(tkwin2)) {
    global.x = floor(global.x);
	    if (tkwin2 == (Tk_Window) grabWinPtr) {
		break;
	    }
	}
	if (tkwin2 != (Tk_Window) grabWinPtr) {
	    return theEvent;
	}
    }

    global.y = floor(TkMacOSXZeroScreenHeight() - global.y);
    /*
     * Convert local from NSWindow flipped coordinates to the toplevel's
     * coordinates.
    local.x = floor(local.x);
     */

    local.y = floor([eventWindow frame].size.height - local.y);
    if (Tk_IsEmbedded(winPtr)) {
	TkWindow *contPtr = TkpGetOtherWindow(winPtr);
	if (Tk_IsTopLevel(contPtr)) {
	    local.x -= contPtr->wmInfoPtr->xInParent;
	    local.y -= contPtr->wmInfoPtr->yInParent;
	} else {
	    TkWindow *topPtr = TkMacOSXGetHostToplevel(winPtr)->winPtr;
	    local.x -= (topPtr->wmInfoPtr->xInParent + contPtr->changes.x);
	    local.y -= (topPtr->wmInfoPtr->yInParent + contPtr->changes.y);
	}
    } else {
	local.x -= winPtr->wmInfoPtr->xInParent;
	local.y -= winPtr->wmInfoPtr->yInParent;
    }

    /*
     * Use the toplevel coordinates to find the containing Tk window.  Then
     * convert local into the coordinates of that window.  (The converted
     * local coordinates are only needed for scrollwheel events.)
     * 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.)
     */

    int win_x, win_y;
    tkwin = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &win_x, &win_y);
    local.x = win_x;
    local.y = win_y;
    target = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &win_x, &win_y);

    /*
     * Ignore the event if a local grab is in effect and the Tk window is
     * not in the grabber's subtree.
     */

    grabWinPtr = winPtr->dispPtr->grabWinPtr;
    if (grabWinPtr && /* There is a grab in effect ... */
	!winPtr->dispPtr->grabFlags && /* and it is a local grab ... */
	grabWinPtr->mainPtr == winPtr->mainPtr){ /* in the same application. */
	Tk_Window tkwin2;
	if (!target) {
	    return theEvent;
	}
	for (tkwin2 = target;
	     !Tk_IsTopLevel(tkwin2);
	     tkwin2 = Tk_Parent(tkwin2)) {
	    if (tkwin2 == (Tk_Window)grabWinPtr) {
		break;
	    }
	}
	if (tkwin2 != (Tk_Window)grabWinPtr) {
	    return theEvent;
	}
    }

    /*
     *  Generate an XEvent for this mouse event.
     */

    unsigned int state = 0;
    unsigned int state = buttonState;
    if (button > 0) {
	state |= TkGetButtonMask(button);
    }

    NSUInteger modifiers = [theEvent modifierFlags];

    if (modifiers & NSAlphaShiftKeyMask) {
	state |= LockMask;
    }
    if (modifiers & NSShiftKeyMask) {
	state |= ShiftMask;
255
256
257
258
259
260
261
262



263
264
265
266
267


268

269

270


271
272
273
274
275
276
277
278
279
280
281
282


283
284
285
286
287


288
289

290
291
292
293
294

295
296
297
298

299
300
301
302
303

304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
291
292
293
294
295
296
297

298
299
300
301
302
303


304
305
306
307

308
309
310
311
312
313
314
315
316




317


318
319
320
321
322


323
324
325

326
327


328

329
330
331
332

333
334


335

336
337
338
339
340
341
342
343
344
345




























346
347
348
349
350
351
352







-
+
+
+



-
-
+
+

+
-
+

+
+





-
-
-
-

-
-
+
+



-
-
+
+

-
+

-
-

-
+



-
+

-
-

-
+









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







    if (modifiers & NSFunctionKeyMask) {
	state |= Mod4Mask;
    }

    if (eventType != NSScrollWheel) {

	/*
	 * For normal mouse events, Tk_UpdatePointer will send the XEvent.
	 * For normal mouse events, Tk_UpdatePointer will send the appropriate
	 * XEvents using its cached state information.  Unfortunately, it will
	 * also recompute the local coordinates.
	 */

#ifdef TK_MAC_DEBUG_EVENTS
	TKLog(@"UpdatePointer %p x %f.0 y %f.0 %d",
		tkwin, global.x, global.y, state);
	TKLog(@"UpdatePointer %p x %.1f y %.1f %d",
		target, global.x, global.y, state);
#endif

	Tk_UpdatePointer(tkwin, global.x, global.y, state);
	Tk_UpdatePointer(target, global.x, global.y, state);
    } else {
	CGFloat delta;
	XEvent xEvent;

	/*
	 * For scroll wheel events we need to send the XEvent here.
	 */

	CGFloat delta;
	int coarseDelta;
	XEvent xEvent;

	xEvent.type = MouseWheelEvent;
	xEvent.xbutton.x = local.x;
	xEvent.xbutton.y = local.y;
	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(tkwin);
	xEvent.xany.window = Tk_WindowId(tkwin);
	xEvent.xany.display = Tk_Display(target);
	xEvent.xany.window = Tk_WindowId(target);

	delta = [theEvent deltaY];
	delta = [theEvent deltaY] * 120;
	if (delta != 0.0) {
	    coarseDelta = (delta > -1.0 && delta < 1.0) ?
		    (signbit(delta) ? -1 : 1) : lround(delta);
	    xEvent.xbutton.state = state;
	    xEvent.xkey.keycode = coarseDelta;
	    xEvent.xkey.keycode = (delta > 0) ? ceil(delta) : floor(delta);
	    xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
	    Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
	}
	delta = [theEvent deltaX];
	delta = [theEvent deltaX] * 120;
	if (delta != 0.0) {
	    coarseDelta = (delta > -1.0 && delta < 1.0) ?
		    (signbit(delta) ? -1 : 1) : lround(delta);
	    xEvent.xbutton.state = state | ShiftMask;
	    xEvent.xkey.keycode = coarseDelta;
	    xEvent.xkey.keycode = (delta > 0) ? ceil(delta) : floor(delta);
	    xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
	    Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
	}
    }
    return theEvent;
}
@end

#pragma mark -

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXKeyModifiers --
 *
 *	Returns the current state of the modifier keys.
 *
 * Results:
 *	An OS Modifier state.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

EventModifiers
TkMacOSXModifierState(void)
{
    UInt32 keyModifiers;
    int isFrontProcess = (GetCurrentEvent() && Tk_MacOSXIsAppInFront());

    keyModifiers = isFrontProcess ? GetCurrentEventKeyModifiers() :
	    GetCurrentKeyModifiers();

    return (EventModifiers) (keyModifiers & USHRT_MAX);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXButtonKeyState --
 *
 *	Returns the current state of the button & modifier keys.
394
395
396
397
398
399
400
401
402









403
404
405
406
407
408
409
399
400
401
402
403
404
405


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







-
-
+
+
+
+
+
+
+
+
+







{
    unsigned int state;

    /*
     * Tk on OSX supports at most 9 buttons.
     */

    state = (buttonState & 0x7F) * Button1Mask;
    /* Handle buttons 8/9 */
    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;
464
465
466
467
468
469
470
471
472


473
474
475
476
477
478
479
476
477
478
479
480
481
482


483
484
485
486
487
488
489
490
491







-
-
+
+







    (void)root_return;
    (void)child_return;

    if (getGlobal || getLocal) {
	NSPoint global = [NSEvent mouseLocation];

	if (getLocal) {
	    MacDrawable *macWin = (MacDrawable *) w;
	    NSWindow *win = TkMacOSXDrawableWindow(w);
	    MacDrawable *macWin = (MacDrawable *)w;
	    NSWindow *win = TkMacOSXGetNSWindowForDrawable(w);

	    if (win) {
		NSPoint local;

		local = [win tkConvertPointFromScreen:global];
		local.y = [win frame].size.height - local.y;
		if (macWin->winPtr && macWin->winPtr->wmInfoPtr) {
503
504
505
506
507
508
509
510

511
512
513
514
515
516
517
515
516
517
518
519
520
521

522
523
524
525
526
527
528
529







-
+







 *	This procedure generates an X button event for the current pointer
 *	state as reported by XQueryPointer().
 *
 * Results:
 *	True if event(s) are generated - false otherwise.
 *
 * Side effects:
 *	Additional events may be place on the Tk event queue. Grab state may
 *	Additional events may be placed on the Tk event queue. Grab state may
 *	also change.
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE int
TkGenerateButtonEventForXPointer(
541
542
543
544
545
546
547
548

549
550
551
552
553
554
555
556
557
558
559
560
561
562


563
564
565
566
567
568
569
553
554
555
556
557
558
559

560
561
562
563
564
565
566
567
568
569
570
571
572


573
574
575
576
577
578
579
580
581







-
+












-
-
+
+







 *	generates the appropriate X button event. It also handles the state
 *	changes needed to implement implicit grabs.
 *
 * Results:
 *	True if event(s) are generated, false otherwise.
 *
 * Side effects:
 *	Additional events may be place on the Tk event queue. Grab state may
 *	Additional events may be placed on the Tk event queue. Grab state may
 *	also change.
 *
 *----------------------------------------------------------------------
 */

int
TkGenerateButtonEvent(
    int x,			/* X location of mouse, */
    int y,			/* Y location of mouse. */
    Window window,		/* X Window containing button event. */
    unsigned int state)		/* Button Key state suitable for X event. */
{
    MacDrawable *macWin = (MacDrawable *) window;
    NSWindow *win = TkMacOSXDrawableWindow(window);
    MacDrawable *macWin = (MacDrawable *)window;
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(window);
    MouseEventData med;

    bzero(&med, sizeof(MouseEventData));
    med.state = state;
    med.window = window;
    med.global.h = x;
    med.global.v = y;
593
594
595
596
597
598
599
600

601
602
603
604
605
606
607
608
609
610
611
612
613
614

615
616
617
618
619
620
621
605
606
607
608
609
610
611

612
613
614
615
616
617
618
619
620
621
622
623
624
625

626
627
628
629
630
631
632
633







-
+













-
+







 *	Generate an X button event from a MouseEventData structure. Handles
 *	the state changes needed to implement implicit grabs.
 *
 * Results:
 *	True if event(s) are generated - false otherwise.
 *
 * Side effects:
 *	Additional events may be place on the Tk event queue. Grab state may
 *	Additional events may be placed on the Tk event queue. Grab state may
 *	also change.
 *
 *----------------------------------------------------------------------
 */

static int
GenerateButtonEvent(
    MouseEventData *medPtr)
{
    Tk_Window tkwin;
    int dummy;
    TkDisplay *dispPtr;

#if UNUSED
#ifdef UNUSED

    /*
     * ButtonDown events will always occur in the front window. ButtonUp
     * events, however, may occur anywhere on the screen. ButtonUp events
     * should only be sent to Tk if in the front window or during an implicit
     * grab.
     */
636
637
638
639
640
641
642

















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







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





-
-



-
-
-
-



-
-

-
-
+

-


-
-
-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-







		&dummy, &dummy);
    }

    Tk_UpdatePointer(tkwin, medPtr->global.h, medPtr->global.v, medPtr->state);
    return true;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpWarpPointer --
 *
 *	Move the mouse cursor to the screen location specified by the warpX and
 *	warpY fields of a TkDisplay.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	The mouse cursor is moved.
 *
 *----------------------------------------------------------------------
 */

void
TkpWarpPointer(
    TkDisplay *dispPtr)
{
    CGPoint pt;
    NSPoint loc;
    int wNum;

    if (dispPtr->warpWindow) {
	int x, y;
	TkWindow *winPtr = (TkWindow *) dispPtr->warpWindow;
	TkWindow *topPtr = winPtr->privatePtr->toplevel->winPtr;
	NSWindow *w = TkMacOSXDrawableWindow(winPtr->window);
	wNum = [w windowNumber];
	Tk_GetRootCoords(dispPtr->warpWindow, &x, &y);
	pt.x = x + dispPtr->warpX;
	pt.y = y + dispPtr->warpY;
	loc.x = dispPtr->warpX;
	loc.y = Tk_Height(topPtr) - dispPtr->warpY;
    } else {
	wNum = 0;
	pt.x = loc.x = dispPtr->warpX;
	pt.x = dispPtr->warpX;
	pt.y = dispPtr->warpY;
	loc.y = TkMacOSXZeroScreenHeight() - pt.y;
    }

    /*
     * Generate an NSEvent of type NSMouseMoved.
     *
     * It is not clear why this is necessary.  For example, calling
     *     event generate $w <Motion> -warp 1 -x $X -y $Y
     * will cause two <Motion> events to be added to the Tcl queue.
     */

    CGWarpMouseCursorPosition(pt);
    NSEvent *warpEvent = [NSEvent mouseEventWithType:NSMouseMoved
	location:loc
	modifierFlags:0
	timestamp:GetCurrentEventTime()
	windowNumber:wNum
	context:nil
	eventNumber:0
	clickCount:1
	pressure:0.0];
    [NSApp postEvent:warpEvent atStart:NO];
}

/*
 *----------------------------------------------------------------------
 *
 * TkpSetCapture --
 *
708
709
710
711
712
713
714
715
716

717
718
719
720
721
722
723
709
710
711
712
713
714
715


716
717
718
719
720
721
722
723







-
-
+







void
TkpSetCapture(
    TkWindow *winPtr)		/* Capture window, or NULL. */
{
    while (winPtr && !Tk_IsTopLevel(winPtr)) {
	winPtr = winPtr->parentPtr;
    }
    [NSEvent stopPeriodicEvents];
    captureWinPtr = (Tk_Window) winPtr;
    captureWinPtr = (Tk_Window)winPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetCapture --
 *

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
1
2
3
4
5
6




7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53






-
-
-
-
+
+
+
+








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







/*
 * 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 <[email protected]>
 * Copyright 2015 Marc Culler.
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009, Apple Inc.
 * Copyright © 2005-2009 Daniel A. Steffen <[email protected]>
 * 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 "tkMacOSXInt.h"
#include "tkMacOSXConstants.h"
#if TCL_MAJOR_VERSION < 9
#undef Tcl_MacOSXNotifierAddRunLoopMode
#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 TclIntPlatStubs {
    int magic;
    void *hooks;
    void (*dummy[19]) (void); /* dummy entries 0-18, not used */
    void (*tclMacOSXNotifierAddRunLoopMode) (const void *runLoopMode); /* 19 */
#include <tclInt.h>
} TclIntPlatStubs;
extern const TclIntPlatStubs *tclIntPlatStubsPtr;
#ifdef __cplusplus
}
#endif
#define Tcl_MacOSXNotifierAddRunLoopMode \
	(tclIntPlatStubsPtr->tclMacOSXNotifierAddRunLoopMode) /* 19 */
#elif TCL_MINOR_VERSION < 7
    extern void TclMacOSXNotifierAddRunLoopMode(const void *runLoopMode);
#   define Tcl_MacOSXNotifierAddRunLoopMode TclMacOSXNotifierAddRunLoopMode
#else
    extern void Tcl_MacOSXNotifierAddRunLoopMode(const void *runLoopMode);
#endif
#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;
152
153
154
155
156
157
158

159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176


177
178
179
180
181
182
183
184
185







186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204

205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240

241
242
243
244
245
246
247


248
249
250
251
252
253
254







+


















+
+









+
+
+
+
+
+
+


















-
+






-
-







     * the "move completed" event without having sent the "move began" event of
     * subtype 20, and then announcing their error on our stderr.  Also, of
     * course, no movement is occurring.  The popup is not movable and is just
     * being closed.  The bug has been reported to Apple.  If they ever fix it,
     * this block should be removed.
     */

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101500
    if ([theEvent type] == NSAppKitDefined) {
	static Bool aWindowIsMoving = NO;
	switch([theEvent subtype]) {
	case 20:
	    aWindowIsMoving = YES;
	    break;
	case 21:
	    if (aWindowIsMoving) {
		aWindowIsMoving = NO;
		break;
	    } else {
		// printf("Bug!!!!\n");
		return;
	    }
	default:
	    break;
	}
    }
#endif

    [super sendEvent:theEvent];
    [NSApp tkCheckPasteboard];

#ifdef TK_MAC_DEBUG_EVENTS
    fprintf(stderr, "Sending event of type %d\n", (int)[theEvent type]);
    DebugPrintQueue();
#endif

}

- (void) _runBackgroundLoop
{
    while(Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_TIMER_EVENTS|TCL_DONT_WAIT)){
	TkMacOSXDrawAllViews(NULL);
    }
}
@end

#pragma mark -

/*
 *----------------------------------------------------------------------
 *
 * GetRunLoopMode --
 *
 * Results:
 *	RunLoop mode that should be passed to -nextEventMatchingMask:
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

NSString *
static NSString *
GetRunLoopMode(NSModalSession modalSession)
{
    NSString *runLoopMode = nil;

    if (modalSession) {
	runLoopMode = NSModalPanelRunLoopMode;
    } else if (TkpGetCapture()) {
	runLoopMode = NSEventTrackingRunLoopMode;
    }
    if (!runLoopMode) {
	runLoopMode = [[NSRunLoop currentRunLoop] currentMode];
    }
    if (!runLoopMode) {
	runLoopMode = NSDefaultRunLoopMode;
    }
257
258
259
260
261
262
263
264
265
266


267
268
269
270
271
272
273
292
293
294
295
296
297
298



299
300
301
302
303
304
305
306
307







-
-
-
+
+








		Tcl_Panic("Tk_MacOSXSetupTkNotifier: %s",
		    "first [load] of TkAqua has to occur in the main thread!");
	    }
	    Tcl_CreateEventSource(TkMacOSXEventsSetupProc,
		    TkMacOSXEventsCheckProc, NULL);
	    TkCreateExitHandler(TkMacOSXNotifyExitHandler, NULL);
	    Tcl_SetServiceMode(TCL_SERVICE_ALL);
	    TclMacOSXNotifierAddRunLoopMode(NSEventTrackingRunLoopMode);
	    TclMacOSXNotifierAddRunLoopMode(NSModalPanelRunLoopMode);
	    Tcl_MacOSXNotifierAddRunLoopMode(NSEventTrackingRunLoopMode);
	    Tcl_MacOSXNotifierAddRunLoopMode(NSModalPanelRunLoopMode);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
296
297
298
299
300
301
302
















































































303
304
305
306

307
308
309
310
311
312
313
314
315

316
317


318
319
320
321















322
323
324
325
326
327
328
329
330
331
332
333
334
335
336

337
338
339
340
341









342
343
344
345
346
347
348

349
350

351
352


353
354

355
356
357
358




359
360

361
362
363
364

365
366
367
368
369
370
371
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419

420
421
422
423
424
425
426
427
428
429
430


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

457
458
459
460
461
462
463
464

465
466
467



468
469
470
471
472
473
474
475
476
477
478
479
480
481
482

483


484


485
486


487
488
489


490
491
492
493


494
495
496


497
498
499
500
501
502
503
504







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



-
+









+
-
-
+
+




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





-








-
+


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






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


-
-
+
+
+
+
-
-
+


-
-
+







	    TkMacOSXEventsCheckProc, NULL);
    tsdPtr->initialized = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXDrawAllViews --
 *
 *       This static function is meant to be run as an idle task.  It attempts
 *       to redraw all views which have the tkNeedsDisplay property set to YES.
 *       This relies on a feature of [NSApp nextEventMatchingMask: ...] which
 *       is undocumented, namely that it sometimes blocks and calls drawRect
 *       for all views that need display before it returns.  We call it with
 *       deQueue=NO so that it will not change anything on the AppKit event
 *       queue, because we only want the side effect that it runs drawRect. The
 *       only time when any NSViews have the needsDisplay property set to YES
 *       is during execution of this function.
 *
 *       The reason for running this function as an idle task is to try to
 *       arrange that all widgets will be fully configured before they are
 *       drawn.  Any idle tasks that might reconfigure them should be higher on
 *       the idle queue, so they should be run before the display procs are run
 *       by drawRect.
 *
 *       If this function is called directly with non-NULL clientData parameter
 *       then the int which it references will be set to the number of windows
 *       that need display, but the needsDisplay property of those windows will
 *       not be changed.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Parts of windows 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 setNeedsDisplayInRect:[view tkDirtyRect]];
	    }
	} else {
	    [window displayIfNeeded];
	}
    }
    if (dirtyCount) {
    	*dirtyCount = count;
    }
    [NSApp nextEventMatchingMask:NSAnyEventMask
		       untilDate:[NSDate distantPast]
			  inMode:GetRunLoopMode(TkMacOSXGetModalSession())
			 dequeue:NO];
    for (NSWindow *window in [NSApp windows]) {
	if ([[window contentView] isMemberOfClass:[TKContentView class]]) {
	    TKContentView *view = [window contentView];

	    /*
	     * If we did not run drawRect, we set needsDisplay back to NO.
	     * Note that if drawRect did run it may have added to Tk's dirty
	     * rect, due to attempts to draw outside of drawRect's dirty rect.
	     */

	    if ([view needsDisplay]) {
		[view setNeedsDisplay: NO];
	    }
	}
    }
    [NSApp setNeedsToDraw:NO];
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXEventsSetupProc --
 *
 *	This procedure implements the setup part of the MacOSX event source. It
 *	is invoked by Tcl_DoOneEvent before calling TkMacOSXEventsProc to
 *	is invoked by Tcl_DoOneEvent before calling TkMacOSXEventsCheckProc to
 *	process all queued NSEvents.  In our case, all we need to do is to set
 *	the Tcl MaxBlockTime to 0 before starting the loop to process all
 *	queued NSEvents.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *
 *	If NSEvents are queued, or if there is any drawing that needs to be
 *	If NSEvents are queued, then the maximum block time will be set to 0 to
 *	ensure that control returns immediately to Tcl.
 *      done, then the maximum block time will be set to 0 to ensure that
 *      Tcl_WaitForEvent returns immediately.
 *
 *----------------------------------------------------------------------
 */

#define TICK 200
static Tcl_TimerToken ticker = NULL;

static void
Heartbeat(
    TCL_UNUSED(ClientData))
{

    if (ticker) {
	ticker = Tcl_CreateTimerHandler(TICK, Heartbeat, NULL);
    }
}

static const Tcl_Time zeroBlockTime = { 0, 0 };

static void
TkMacOSXEventsSetupProc(
    ClientData dummy,
    int flags)
{
    static Bool havePeriodicEvents = NO;
    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) {
	static const Tcl_Time zeroBlockTime = { 0, 0 };

	[NSApp _resetAutoreleasePool];

	/*
	 * Call this with dequeue=NO -- just checking if the queue is empty.
	 */
 	/*
	 * 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 heartbeat.
  	 */

	NSEvent *currentEvent =
	        [NSApp nextEventMatchingMask:NSAnyEventMask
			untilDate:[NSDate distantPast]
			inMode:GetRunLoopMode(TkMacOSXGetModalSession())
			dequeue:NO];
	if (currentEvent) {
	if ((currentEvent) || [NSApp needsToDraw] ) {
	    if (currentEvent.type > 0) {
		Tcl_SetMaxBlockTime(&zeroBlockTime);
	    Tcl_SetMaxBlockTime(&zeroBlockTime);
		[NSEvent stopPeriodicEvents];
		havePeriodicEvents = NO;
	    Tcl_DeleteTimerHandler(ticker);
	    ticker = NULL;
	    }
	} else if (!havePeriodicEvents){
	} else if (ticker == NULL) {

	    /*
	     * When the user is not generating events we schedule a "hearbeat"
	     * event to fire every 0.1 seconds.  This helps to make the vwait
	     * When the user is not generating events we schedule a "heartbeat"
	     * TimerHandler to fire every 200 milliseconds.  The handler does
	     * nothing, but when its timer fires it causes Tcl_WaitForEvent to
	     * return.  This helps avoid hangs when calling vwait during the
	     * command more responsive when there is no user input, e.g. when
	     * running the test suite.
	     * non-regression tests.
	     */

	    havePeriodicEvents = YES;
	    [NSEvent startPeriodicEventsAfterDelay:0.0 withPeriod:0.1];
	    ticker = Tcl_CreateTimerHandler(TICK, Heartbeat, NULL);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
381
382
383
384
385
386
387
388

389
390
391
392

393
394
395
396
397
398
399
514
515
516
517
518
519
520

521
522
523
524

525
526
527
528
529
530
531
532







-
+



-
+







 *	NSevents are used to generate X events, which are added to the Tcl
 *      event queue.
 *
 *----------------------------------------------------------------------
 */
static void
TkMacOSXEventsCheckProc(
    ClientData dummy,
    TCL_UNUSED(ClientData),
    int flags)
{
    NSString *runloopMode = [[NSRunLoop currentRunLoop] currentMode];
    (void)dummy;
    int eventsFound = 0;

    /*
     * runloopMode will be nil if we are in a Tcl event loop.
     */

    if (flags & TCL_WINDOW_EVENTS && !runloopMode) {
	NSEvent *currentEvent = nil;
424
425
426
427
428
429
430

431
432
433
434
435
436
437
438


439
440
441

442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457



















458
459
460
461
462
463
464
465
466
467
468
557
558
559
560
561
562
563
564
565
566
567
568

569

570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622







+




-

-

+
+



+
















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











		break;
	    }
	    currentEvent = [NSApp nextEventMatchingMask:NSAnyEventMask
		    untilDate:[NSDate distantPast]
		    inMode:GetRunLoopMode(modalSession)
		    dequeue:YES];
	    if (currentEvent) {

		/*
		 * Generate Xevents.
		 */

		int oldServiceMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
		NSEvent *processedEvent = [NSApp tkProcessEvent:currentEvent];
		Tcl_SetServiceMode(oldServiceMode);
		if (processedEvent) {
		    eventsFound++;

#ifdef TK_MAC_DEBUG_EVENTS
		    TKLog(@"   event: %@", currentEvent);
#endif

		    if (modalSession) {
			[NSApp _modalSession:modalSession sendEvent:currentEvent];
		    } else {
			[NSApp sendEvent:currentEvent];
		    }
		}
	    } else {
		break;
	    }
	} while (1);

	/*
	 * Now we can unlock the pool.
	 */

	[NSApp _unlockAutoreleasePool];

	/*
	 * Add an idle task to the end of the idle queue which will redisplay
	 * all of our dirty windows.  We want this to happen after all other
	 * idle tasks have run so that all widgets will be configured before
	 * they are displayed.  The drawRect method "borrows" the idle queue
	 * while drawing views. That is, it sends expose events which cause
	 * display procs to be posted as idle tasks and then runs an inner
	 * event loop to processes those idle tasks.  We are trying to arrange
	 * for the idle queue to be empty when it starts that process and empty
	 * when it finishes.
	 */

	int dirtyCount = 0;
	TkMacOSXDrawAllViews(&dirtyCount);
	if (dirtyCount > 0) {
	    Tcl_CancelIdleCall(TkMacOSXDrawAllViews, NULL);
	    Tcl_DoWhenIdle(TkMacOSXDrawAllViews, NULL);
	}
    }
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXPort.h.

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

43
44
45


46
47
48
49
50
51
52
53
54
31
32
33
34
35
36
37





38
39


40
41


42
43
44
45
46
47
48







-
-
-
-
-
+

-
-
+
+
-
-







#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
#if HAVE_SYS_TIME_H
#	include <sys/time.h>
#   else
#	include <time.h>
#endif
#include <time.h>
#   endif
#endif
#if HAVE_INTTYPES_H
#    include <inttypes.h>
#endif
#include <unistd.h>
#if defined(__GNUC__) && !defined(__cplusplus)
#   pragma GCC diagnostic ignored "-Wc++-compat"
#endif
127
128
129
130
131
132
133


134
135
136
137
138
139








140
141
142
143
144



145
146
147
148
149
150

151
152

153
154



155
156



157



158
159
121
122
123
124
125
126
127
128
129
130
131




132
133
134
135
136
137
138
139
140
141



142
143
144
145
146




147
148
149
150


151
152
153


154
155
156
157
158
159
160
161
162







+
+


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


-
-
-
+
+
+


-
-
-
-
+


+
-
-
+
+
+
-
-
+
+
+

+
+
+


	sprintf((buf), "0x%lx", (unsigned long) (w))

/*
 * Turn off Tk double-buffering as Aqua windows are already double-buffered.
 */

#define TK_NO_DOUBLE_BUFFERING 1
#define TK_HAS_DYNAMIC_COLORS 1
#define TK_DYNAMIC_COLORMAP 0x0fffffff

/*
 * Magic pixel code values for system colors.
 *
 * NOTE: values must be kept in sync with indices into the
 *	 systemColorMap array in tkMacOSXColor.c !
 * Inform tkImgPhInstance.c that our tkPutImage can render an image with an
 * alpha channel directly into a window.
 */

#define TKPUTIMAGE_CAN_BLEND

/*
 * Used by xcolor.c
 */

#define TRANSPARENT_PIXEL		30
#define APPEARANCE_PIXEL		52
#define PIXEL_MAGIC ((unsigned char) 0x69)
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))

/*
 * The following macro returns the pixel value that corresponds to the
 * 16-bit RGB values in the given XColor structure.
 * The format is: (PIXEL_MAGIC << 24) | (R << 16) | (G << 8) | B
 * where each of R, G and B is the high order byte of a 16-bit component.
 * Used by tkWindow.c
 */

MODULE_SCOPE void TkMacOSXHandleMapOrUnmap(Tk_Window tkwin, XEvent *event);
#define TkpGetPixel(p) ((((((PIXEL_MAGIC << 8) \
	| (((p)->red >> 8) & 0xff)) << 8) \

#define TkpHandleMapOrUnmap(tkwin, event)  TkMacOSXHandleMapOrUnmap(tkwin, event)

	| (((p)->green >> 8) & 0xff)) << 8) \
	| (((p)->blue >> 8) & 0xff))
/*
 * 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
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





-
-
+
+
+



















+

+







/*
 * tkMacOSXPrivate.h --
 *
 *	Macros and declarations that are purely internal & private to TkAqua.
 *
 * Copyright (c) 2005-2009 Daniel A. Steffen <[email protected]>
 * Copyright 2008-2009, Apple Inc.
 * Copyright © 2005-2009 Daniel A. Steffen <[email protected]>
 * 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$
 */

#ifndef _TKMACPRIV
#define _TKMACPRIV

#if !__OBJC__
#error Objective-C compiler required
#endif

#ifndef __clang__
#define instancetype id
#endif

#define TextStyle MacTextStyle
#define Cursor QDCursor
#import <ApplicationServices/ApplicationServices.h>
#undef Cursor
#import <Cocoa/Cocoa.h>
#ifndef NO_CARBON_H
#import <Carbon/Carbon.h>
#endif
#undef TextStyle
#import <objc/runtime.h> /* for sel_isEqual() */

98
99
100
101
102
103
104
105
106
107



108
109

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



108
109
110
111

112
113
114
115
116
117
118
119







-
-
-
+
+
+

-
+







    } while (0)

/*
 * Macro to do very common check for noErr return from given API and output
 * debug message in case of failure.
 */
#define ChkErr(f, ...) ({ \
	OSStatus err = f(__VA_ARGS__); \
	if (err != noErr) { \
	    TkMacOSXDbgOSErr(f, err); \
	OSStatus err_ = f(__VA_ARGS__); \
	if (err_ != noErr) { \
	    TkMacOSXDbgOSErr(f, err_); \
	} \
	err;})
	err_;})

#else /* TK_MAC_DEBUG */
#define TKLog(f, ...)
#define TkMacOSXDbgMsg(m, ...)
#define TkMacOSXDbgOSErr(f, err)
#define ChkErr(f, ...) ({f(__VA_ARGS__);})
#endif /* TK_MAC_DEBUG */
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266

267
268
269
270
271
272
273
274




275
276
277
278
279
280
281
282
283
284

285
286

287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307

308
309







310
311
312
313
314
315
316
224
225
226
227
228
229
230




231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250



251
252




253
254
255
256
257

258
259
260
261
262




263
264
265
266



267
268
269
270



271
272

273
274

275

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

292

293
294
295
296
297
298
299
300
301
302
303
304
305
306
307







-
-
-
-




















-
-
-


-
-
-
-





-
+




-
-
-
-
+
+
+
+
-
-
-




-
-
-
+

-
+

-

-
















-
+
-

+
+
+
+
+
+
+







			    HIShapeRef rgn);
MODULE_SCOPE HIShapeRef	TkMacOSXHIShapeCreateEmpty(void);
MODULE_SCOPE HIMutableShapeRef TkMacOSXHIShapeCreateMutableWithRect(
			    const CGRect *inRect);
MODULE_SCOPE OSStatus	TkMacOSXHIShapeSetWithShape(
			    HIMutableShapeRef inDestShape,
			    HIShapeRef inSrcShape);
#if 0
MODULE_SCOPE OSStatus	TkMacOSXHIShapeSetWithRect(HIMutableShapeRef inShape,
			    const CGRect *inRect);
#endif
MODULE_SCOPE OSStatus	TkMacOSHIShapeDifferenceWithRect(
			    HIMutableShapeRef inShape, const CGRect *inRect);
MODULE_SCOPE OSStatus	TkMacOSHIShapeUnionWithRect(HIMutableShapeRef inShape,
			    const CGRect *inRect);
MODULE_SCOPE OSStatus	TkMacOSHIShapeUnion(HIShapeRef inShape1,
			    HIShapeRef inShape2, HIMutableShapeRef outResult);

/*
 * Prototypes of TkAqua internal procs.
 */

MODULE_SCOPE void *	TkMacOSXGetNamedSymbol(const char *module,
			    const char *symbol);
MODULE_SCOPE void	TkMacOSXDisplayChanged(Display *display);
MODULE_SCOPE CGFloat	TkMacOSXZeroScreenHeight();
MODULE_SCOPE CGFloat	TkMacOSXZeroScreenTop();
MODULE_SCOPE int	TkMacOSXUseAntialiasedText(Tcl_Interp *interp,
			    int enable);
MODULE_SCOPE int	TkMacOSXInitCGDrawing(Tcl_Interp *interp, int enable,
			    int antiAlias);
MODULE_SCOPE int	TkMacOSXGenerateFocusEvent(TkWindow *winPtr,
			    int activeFlag);
MODULE_SCOPE WindowClass TkMacOSXWindowClass(TkWindow *winPtr);
MODULE_SCOPE int	TkMacOSXIsWindowZoomed(TkWindow *winPtr);
MODULE_SCOPE int	TkGenerateButtonEventForXPointer(Window window);
MODULE_SCOPE EventModifiers TkMacOSXModifierState(void);
MODULE_SCOPE NSBitmapImageRep* TkMacOSXBitmapRepFromDrawableRect(Drawable drawable,
			    int x, int y, unsigned int width, unsigned int height);
MODULE_SCOPE CGImageRef TkMacOSXCreateCGImageWithXImage(XImage *image);
MODULE_SCOPE void       TkMacOSXDrawCGImage(Drawable d, GC gc, CGContextRef context,
			    CGImageRef image, unsigned long imageForeground,
			    unsigned long imageBackground, CGRect imageBounds,
			    CGRect srcBounds, CGRect dstBounds);
MODULE_SCOPE int	TkMacOSXSetupDrawingContext(Drawable d, GC gc,
			    int useCG, TkMacOSXDrawingContext *dcPtr);
			    TkMacOSXDrawingContext *dcPtr);
MODULE_SCOPE void	TkMacOSXRestoreDrawingContext(
			    TkMacOSXDrawingContext *dcPtr);
MODULE_SCOPE void	TkMacOSXSetColorInContext(GC gc, unsigned long pixel,
			    CGContextRef context);
MODULE_SCOPE int	TkMacOSXMakeFullscreen(TkWindow *winPtr,
			    NSWindow *window, int fullscreen,
			    Tcl_Interp *interp);
MODULE_SCOPE void	TkMacOSXEnterExitFullscreen(TkWindow *winPtr,
#define TkMacOSXGetTkWindow(window) (TkWindow *)Tk_MacOSXGetTkWindow(window)
#define TkMacOSXGetNSWindowForDrawable(drawable) ((NSWindow *)Tk_MacOSXGetNSWindowForDrawable(drawable))
#define TkMacOSXGetNSViewForDrawable(macWin) ((NSView *)Tk_MacOSXGetNSViewForDrawable((Drawable)(macWin)))
#define TkMacOSXGetCGContextForDrawable(drawable) ((CGContextRef)Tk_MacOSXGetCGContextForDrawable(drawable))
			    int active);
MODULE_SCOPE NSWindow*	TkMacOSXDrawableWindow(Drawable drawable);
MODULE_SCOPE NSView*	TkMacOSXDrawableView(MacDrawable *macWin);
MODULE_SCOPE void	TkMacOSXWinCGBounds(TkWindow *winPtr, CGRect *bounds);
MODULE_SCOPE HIShapeRef	TkMacOSXGetClipRgn(Drawable drawable);
MODULE_SCOPE void	TkMacOSXInvalidateViewRegion(NSView *view,
			    HIShapeRef rgn);
MODULE_SCOPE CGContextRef TkMacOSXGetCGContextForDrawable(Drawable drawable);
MODULE_SCOPE CGImageRef	TkMacOSXCreateCGImageWithDrawable(Drawable drawable);
MODULE_SCOPE NSImage*	TkMacOSXGetNSImageWithTkImage(Display *display,
MODULE_SCOPE NSImage*	TkMacOSXGetNSImageFromTkImage(Display *display,
			    Tk_Image image, int width, int height);
MODULE_SCOPE NSImage*	TkMacOSXGetNSImageWithBitmap(Display *display,
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 TkWindow*	TkMacOSXGetTkWindow(NSWindow *w);
MODULE_SCOPE NSFont*	TkMacOSXNSFontForFont(Tk_Font tkfont);
MODULE_SCOPE NSDictionary* TkMacOSXNSFontAttributesForFont(Tk_Font tkfont);
MODULE_SCOPE NSModalSession TkMacOSXGetModalSession(void);
MODULE_SCOPE void	TkMacOSXSelDeadWindow(TkWindow *winPtr);
MODULE_SCOPE void	TkMacOSXApplyWindowAttributes(TkWindow *winPtr,
			    NSWindow *macWindow);
MODULE_SCOPE int	TkMacOSXStandardAboutPanelObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	TkMacOSXIconBitmapObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE void       TkMacOSXDrawSolidBorder(Tk_Window tkwin, GC gc,
			    int inset, int thickness);
MODULE_SCOPE int 	TkMacOSXServices_Init(Tcl_Interp *interp);
MODULE_SCOPE int	TkMacOSXRegisterServiceWidgetObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
			    Tcl_Obj *const objv[]);
MODULE_SCOPE unsigned   TkMacOSXAddVirtual(unsigned int keycode);
MODULE_SCOPE void       TkMacOSXWinNSBounds(TkWindow *winPtr, NSView *view,
					    NSRect *bounds);
MODULE_SCOPE Bool       TkMacOSXInDarkMode(Tk_Window tkwin);
MODULE_SCOPE void	TkMacOSXDrawAllViews(ClientData clientData);
MODULE_SCOPE unsigned long TkMacOSXClearPixel(void);
MODULE_SCOPE int MacSystrayInit(Tcl_Interp *);


#pragma mark Private Objective-C Classes

#define VISIBILITY_HIDDEN __attribute__((visibility("hidden")))

enum { tkMainMenu = 1, tkApplicationMenu, tkWindowsMenu, tkHelpMenu};

333
334
335
336
337
338
339


340
341
342
343
344


345

346
347
348
349


350
351
352
353
354
355
356
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354







+
+





+
+

+




+
+







    Tcl_Interp *_eventInterp;
    NSMenu *_servicesMenu;
    TKMenu *_defaultMainMenu, *_defaultApplicationMenu;
    NSMenuItem *_demoMenuItem;
    NSArray *_defaultApplicationMenuItems, *_defaultWindowsMenuItems;
    NSArray *_defaultHelpMenuItems, *_defaultFileMenuItems;
    NSAutoreleasePool *_mainPool;
    NSThread *_backgoundLoop;

#ifdef __i386__
    /* The Objective C runtime used on i386 requires this. */
    int _poolLock;
    int _macOSVersion;  /* 10000 * major + 100*minor */
    Bool _isDrawing;
    Bool _needsToDraw;
    Bool _isSigned;
#endif

}
@property int poolLock;
@property int macOSVersion;
@property Bool isDrawing;
@property Bool needsToDraw;
@property Bool isSigned;

@end
@interface TKApplication(TKInit)
- (NSString *)tkFrameworkImagePath:(NSString*)image;
- (void)_resetAutoreleasePool;
- (void)_lockAutoreleasePool;
- (void)_unlockAutoreleasePool;
368
369
370
371
372
373
374

375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390

391
392
393
394
395
396
397
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397







+
















+







@end
@interface TKApplication(TKMenus)
- (void) _setupMenus;
@end
@interface NSApplication(TKNotify)
/* We need to declare this hidden method. */
- (void) _modalSession: (NSModalSession) session sendEvent: (NSEvent *) event;
- (void) _runBackgroundLoop;
@end
@interface TKApplication(TKEvent)
- (NSEvent *)tkProcessEvent:(NSEvent *)theEvent;
@end
@interface TKApplication(TKMouseEvent)
- (NSEvent *)tkProcessMouseEvent:(NSEvent *)theEvent;
@end
@interface TKApplication(TKKeyEvent)
- (NSEvent *)tkProcessKeyEvent:(NSEvent *)theEvent;
@end
@interface TKApplication(TKClipboard)
- (void)tkProvidePasteboard:(TkDisplay *)dispPtr;
- (void)tkCheckPasteboard;
@end
@interface TKApplication(TKHLEvents)
- (void) terminate: (id) sender;
- (void) superTerminate: (id) sender;
- (void) preferences: (id) sender;
- (void) handleQuitApplicationEvent:   (NSAppleEventDescriptor *)event
		     withReplyEvent:   (NSAppleEventDescriptor *)replyEvent;
- (void) handleOpenApplicationEvent:   (NSAppleEventDescriptor *)event
		     withReplyEvent:   (NSAppleEventDescriptor *)replyEvent;
- (void) handleReopenApplicationEvent: (NSAppleEventDescriptor *)event
		       withReplyEvent: (NSAppleEventDescriptor *)replyEvent;
413
414
415
416
417
418
419
420


421
422


423
424
425
426
427
428
429
430


431

432
433
434
435
436
437
438
439
440
441









442
443
444
445
446
447
448

449
450




451











452
453
454
455
456
457
458
413
414
415
416
417
418
419

420
421
422

423
424
425
426
427
428
429
430
431
432
433
434

435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460

461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486







-
+
+

-
+
+








+
+
-
+










+
+
+
+
+
+
+
+
+






-
+


+
+
+
+

+
+
+
+
+
+
+
+
+
+
+







 * input from the Character Palette.
 */

@interface TKContentView : NSView <NSTextInputClient>
{
@private
    NSString *privateWorkingText;
    Bool _needsRedisplay;
    Bool _tkNeedsDisplay;
    NSRect _tkDirtyRect;
}
@property Bool needsRedisplay;
@property Bool tkNeedsDisplay;
@property NSRect tkDirtyRect;
@end

@interface TKContentView(TKKeyEvent)
- (void) deleteWorkingText;
- (void) cancelComposingText;
@end

@interface TKContentView(TKWindowEvent)
- (void) addTkDirtyRect: (NSRect) rect;
- (void) clearTkDirtyRect;
- (void) generateExposeEvents: (HIShapeRef) shape;
- (void) generateExposeEvents: (NSRect) rect;
- (void) tkToolbarButton: (id) sender;
@end

@interface NSWindow(TKWm)
- (NSPoint) tkConvertPointToScreen:(NSPoint)point;
- (NSPoint) tkConvertPointFromScreen:(NSPoint)point;
@end

VISIBILITY_HIDDEN
@interface TKWindow : NSWindow
{
#ifdef __i386__
    /* The Objective C runtime used on i386 requires this. */
    Bool _mouseInResizeArea;
    Window _tkWindow;
#endif
}
@property Bool mouseInResizeArea;
@property Window tkWindow;
@end

@interface TKWindow(TKWm)
- (void)    tkLayoutChanged;
@end

@interface NSDrawerWindow : NSWindow
@interface TKDrawerWindow : NSWindow
{
    id _i1, _i2;
#ifdef __i386__
    /* The Objective C runtime used on i386 requires this. */
    Window _tkWindow;
#endif
}
@property Window tkWindow;
@end

@interface TKPanel : NSPanel
{
#ifdef __i386__
    /* The Objective C runtime used on i386 requires this. */
    Window _tkWindow;
#endif
}
@property Window tkWindow;
@end

#pragma mark NSMenu & NSMenuItem Utilities

@interface NSMenu(TKUtils)
+ (id)menuWithTitle:(NSString *)title;
+ (id)menuWithTitle:(NSString *)title menuItems:(NSArray *)items;
532
533
534
535
536
537
538

539
540
541
542
543
544
545
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574







+







 *---------------------------------------------------------------------------
 */

@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
1
2
3
4
5



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31





-
-
-
+
+
+






+
+
+
+
+
+
+
+
+
+







/*
 * 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 <[email protected]>
 * Copyright © 1995-1996 Sun Microsystems, Inc.
 * Copyright © 2001-2009, Apple Inc.
 * Copyright © 2006-2009 Daniel A. Steffen <[email protected]>
 *
 * 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 --
 *
30
31
32
33
34
35
36
37




38
39
40
41
42
43
44
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55
56
57







-
+
+
+
+







 *
 *----------------------------------------------------------------------
 */

Region
XCreateRegion(void)
{
    return (Region) HIShapeCreateMutable();
    Region region = (Region) HIShapeCreateMutable();
    DebugLog("Created region: total regions = %d\n", ++totalRegions);
    RetainRegion(region);
    return region;
}

/*
 *----------------------------------------------------------------------
 *
 * XDestroyRegion --
 *
55
56
57
58
59
60
61

62

63
64
65
66
67
68
69
68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83







+
-
+







 */

int
XDestroyRegion(
    Region r)
{
    if (r) {
	DebugLog("Destroyed region: total regions = %d\n", --totalRegions);
	CFRelease(r);
	ReleaseRegion(r);
    }
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
316
317
318
319
320
321
322
323

324
325
326
327
328
329
330
331
332
333
334
335
336
337


338
339
340

341
342
343
344
345
346

347
348
349
350
351
352
353
354
355
356
357
358
359
360


361
362
363

364
365
366
367
368
369
370
330
331
332
333
334
335
336

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


350
351
352
353
354
355
356
357
358
359
360

361
362
363
364
365
366
367
368
369
370
371
372
373


374
375
376
377
378
379
380
381
382
383
384
385
386







-
+












-
-
+
+



+





-
+












-
-
+
+



+







	dataPtr += lineStride;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpRetainRegion --
 * RetainRegion --
 *
 *	Increases reference count of region.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkpRetainRegion(
static void
RetainRegion(
    Region r)
{
    CFRetain(r);
    DebugLog("Retained region: total count is %d\n", ++totalRegionRetainCount);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpReleaseRegion --
 * ReleaseRegion --
 *
 *	Decreases reference count of region.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May free memory.
 *
 *----------------------------------------------------------------------
 */

void
TkpReleaseRegion(
static void
ReleaseRegion(
    Region r)
{
    CFRelease(r);
    DebugLog("Released region: total count is %d\n", --totalRegionRetainCount);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXSetEmptyRegion --
 *
459
460
461
462
463
464
465
466

467
468
469
470
471
472
473
475
476
477
478
479
480
481

482
483
484
485
486
487
488
489







-
+







    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXHIShapeCreateEmpty, TkMacOSXHIShapeCreateMutableWithRect,
 * TkMacOSXHIShapeSetWithShape, TkMacOSXHIShapeSetWithRect,
 * TkMacOSXHIShapeSetWithShape,
 * TkMacOSHIShapeDifferenceWithRect, TkMacOSHIShapeUnionWithRect,
 * TkMacOSHIShapeUnion --
 *
 *	Wrapper functions for missing/buggy HIShape API
 *
 *----------------------------------------------------------------------
 */
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
514
515
516
517
518
519
520
















521
522
523
524
525
526
527







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







{
    OSStatus result;

    result = HIShapeSetWithShape(inDestShape, inSrcShape);
    return result;
}

#if 0
OSStatus
TkMacOSXHIShapeSetWithRect(
    HIMutableShapeRef inShape,
    const CGRect *inRect)
{
    OSStatus result;
    HIShapeRef rgn = HIShapeCreateWithRect(inRect);

    result = TkMacOSXHIShapeSetWithShape(inShape, rgn);
    CFRelease(rgn);

    return result;
}
#endif

OSStatus
TkMacOSHIShapeDifferenceWithRect(
    HIMutableShapeRef inShape,
    const CGRect *inRect)
{
    OSStatus result;
    HIShapeRef rgn = HIShapeCreateWithRect(inRect);

Changes to macosx/tkMacOSXScale.c.

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 <[email protected]>
 * Copyright 2008-2009, Apple Inc.
 * Copyright © 1996 Sun Microsystems, Inc.
 * Copyright © 1998-2000 Scriptics Corporation.
 * Copyright © 2006-2009 Daniel A. Steffen <[email protected]>
 * 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"
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_Window tkwin = scalePtr->tkwin;
    Tcl_Interp *interp = scalePtr->interp;
    int result;
    char string[TCL_DOUBLE_SPACE];
    MacScale *macScalePtr = clientData;
    Rect r;
    WindowRef windowRef;
    CGrafPtr destPort, savePort;
    Boolean portChanged;
    MacDrawable *macDraw;
    SInt32 initialValue, minValue, maxValue;
    UInt16 numTicks;
    Tcl_DString buf;

#ifdef TK_MAC_DEBUG_SCALE
    TkMacOSXDbgMsg("TkpDisplayScale");
211
212
213
214
215
216
217
218

219
220
221
222

223
224
225
226
227
228
229
209
210
211
212
213
214
215

216




217
218
219
220
221
222
223
224







-
+
-
-
-
-
+







	    Tk_Height(tkwin) - 2*scalePtr->highlightWidth,
	    scalePtr->borderWidth, scalePtr->relief);

    /*
     * Set up port for drawing Macintosh control.
     */

    macDraw = (MacDrawable *) Tk_WindowId(tkwin);
    macDraw = (MacDrawable *)Tk_WindowId(tkwin);
    destPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin));
    windowRef = TkMacOSXDrawableWindow(Tk_WindowId(tkwin));
    portChanged = QDSwapPort(destPort, &savePort);
    TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin));
    windowRef = TkMacOSXGetNSWindowForDrawable(Tk_WindowId(tkwin));

    /*
     * Create Macintosh control.
     */

#define MAC_OSX_SCROLL_WIDTH 10

289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
284
285
286
287
288
289
290



291
292
293
294
295
296
297







-
-
-







     * Finally draw the control.
     */

    SetControlVisibility(macScalePtr->scaleHandle, true, true);
    HiliteControl(macScalePtr->scaleHandle, 0);
    Draw1Control(macScalePtr->scaleHandle);

    if (portChanged) {
	QDSwapPort(savePort, NULL);
    }
done:
    scalePtr->flags &= ~REDRAW_ALL;
}

/*
 *----------------------------------------------------------------------
 *
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
315
316
317
318
319
320
321


322
323
324
325


326
327
328
329
330
331
332
333
334
335
336




337
338
339
340
341
342
343







-
-




-
-











-
-
-
-







    TkScale *scalePtr,		/* Widget record for scale. */
    int x, int y)		/* Coordinates within scalePtr's window. */
{
    MacScale *macScalePtr = (MacScale *) scalePtr;
    ControlPartCode part;
    Point where;
    Rect bounds;
    CGrafPtr destPort, savePort;
    Boolean portChanged;

#ifdef TK_MAC_DEBUG_SCALE
    TkMacOSXDbgMsg("TkpScaleElement");
#endif
    destPort = TkMacOSXGetDrawablePort(Tk_WindowId(scalePtr->tkwin));
    portChanged = QDSwapPort(destPort, &savePort);

    /*
     * All of the calculations in this procedure mirror those in
     * DisplayScrollbar. Be sure to keep the two consistent.
     */

    TkMacOSXWinBounds((TkWindow *) scalePtr->tkwin, &bounds);
    where.h = x + bounds.left;
    where.v = y + bounds.top;
    part = TestControl(macScalePtr->scaleHandle, where);

    if (portChanged) {
	QDSwapPort(savePort, NULL);
    }

#ifdef TK_MAC_DEBUG_SCALE
    fprintf (stderr,"ScalePart %d, pos ( %d %d )\n", part, where.h, where.v );
#endif

    switch (part) {
    case inSlider:
	return SLIDER;
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
381
382
383
384
385
386
387


388
389
390
391
392
393
394
395
396
397
398








399
400
401
402
403
404
405







-
-











-
-
-
-
-
-
-
-







    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    MacScale *macScalePtr = (MacScale *) clientData;
    Point where;
    Rect bounds;
    int part;
    CGrafPtr destPort, savePort;
    Boolean portChanged;

#ifdef TK_MAC_DEBUG_SCALE
    fprintf(stderr,"MacScaleEventProc\n" );
#endif

    /*
     * To call Macintosh control routines we must have the port set to the
     * window containing the control. We will then test which part of the
     * control was hit and act accordingly.
     */

    destPort = TkMacOSXGetDrawablePort(Tk_WindowId(macScalePtr->info.tkwin));
    portChanged = QDSwapPort(destPort, &savePort);
    TkMacOSXSetUpClippingRgn(Tk_WindowId(macScalePtr->info.tkwin));

    TkMacOSXWinBounds((TkWindow *) macScalePtr->info.tkwin, &bounds);
    where.h = eventPtr->xbutton.x + bounds.left;
    where.v = eventPtr->xbutton.y + bounds.top;
#ifdef TK_MAC_DEBUG_SCALE
    TkMacOSXDbgMsg("calling TestControl");
#endif
    part = TestControl(macScalePtr->scaleHandle, where);
    if (part == 0) {
	return;
    }

443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
417
418
419
420
421
422
423




424
425
426
427
428
429
430







-
-
-
-








    /*
     * The HandleControlClick call will "eat" the ButtonUp event. We now
     * generate a ButtonUp event so Tk will unset implicit grabs etc.
     */

    TkGenerateButtonEventForXPointer(Tk_WindowId(macScalePtr->info.tkwin));

    if (portChanged) {
	QDSwapPort(savePort, NULL);
    }
}

/*
 *--------------------------------------------------------------
 *
 * ScaleActionProc --
 *

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 <[email protected]>
 * 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 <[email protected]>
 * 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"
170
171
172
173
174
175
176
177
178


179
180
181
182
183
184
185
170
171
172
173
174
175
176


177
178
179
180
181
182
183
184
185







-
-
+
+







 */

static void drawMacScrollbar(
    TkScrollbar *scrollPtr,
    MacScrollbar *msPtr,
    CGContextRef context)
{
    MacDrawable *macWin = (MacDrawable *) Tk_WindowId(scrollPtr->tkwin);
    NSView *view = TkMacOSXDrawableView(macWin);
    Drawable d = Tk_WindowId(scrollPtr->tkwin);
    NSView *view = TkMacOSXGetNSViewForDrawable(d);
    CGPathRef path;
    CGPoint inner[2], outer[2], thumbOrigin;
    CGSize thumbSize;
    CGRect troughBounds = msPtr->info.bounds;
    troughBounds.origin.y = [view bounds].size.height -
	(troughBounds.origin.y + troughBounds.size.height);
    if (scrollPtr->vertical) {
254
255
256
257
258
259
260
261
262


263
264
265
266

267
268
269
270
271
272
273
254
255
256
257
258
259
260


261
262
263
264
265

266
267
268
269
270
271
272
273







-
-
+
+



-
+








    scrollPtr->flags &= ~REDRAW_PENDING;

    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
	return;
    }

    MacDrawable *macWin = (MacDrawable *) winPtr->window;
    NSView *view = TkMacOSXDrawableView(macWin);
    MacDrawable *macWin = (MacDrawable *)winPtr->window;
    NSView *view = TkMacOSXGetNSViewForDrawable(macWin);

    if ((view == NULL)
	    || (macWin->flags & TK_DO_NOT_DRAW)
	    || !TkMacOSXSetupDrawingContext((Drawable) macWin, NULL, 1, &dc)) {
	    || !TkMacOSXSetupDrawingContext((Drawable)macWin, NULL, &dc)) {
	return;
    }

    /*
     * Transform NSView coordinates to CoreGraphics coordinates.
     */

586
587
588
589
590
591
592
593

594
595
596
597
598

599
600
601
602
603
604
605
586
587
588
589
590
591
592

593
594
595
596
597

598
599
600
601
602
603
604
605







-
+




-
+








static void
UpdateControlValues(
    TkScrollbar *scrollPtr)		/* Scrollbar data struct. */
{
    MacScrollbar *msPtr = (MacScrollbar *) scrollPtr;
    Tk_Window tkwin = scrollPtr->tkwin;
    MacDrawable *macWin = (MacDrawable *) Tk_WindowId(scrollPtr->tkwin);
    MacDrawable *macWin = (MacDrawable *)Tk_WindowId(scrollPtr->tkwin);
    double dViewSize;
    HIRect contrlRect;
    short width, height;

    NSView *view = TkMacOSXDrawableView(macWin);
    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);
658
659
660
661
662
663
664
665

666
667
668
669
670
671
672
658
659
660
661
662
663
664

665
666
667
668
669
670
671
672







-
+







}

/*
 *--------------------------------------------------------------
 *
 * ScrollbarEvent --
 *
 *	This procedure is invoked in response to <ButtonPress>,
 *	This procedure is invoked in response to <Button>,
 *      <ButtonRelease>, <EnterNotify>, and <LeaveNotify> events.  The
 *      Scrollbar appearance is modified for each event.
 *
 *--------------------------------------------------------------
 */

static int

Changes to macosx/tkMacOSXSend.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





-
+


















-
-
-
-
+
+
+
+







/*
 * tkMacOSXSend.c --
 *
 *	This file provides procedures that implement the "send" command,
 *	allowing commands to be passed from interpreter to interpreter. This
 *	current implementation for the Mac has most functionality stubed out.
 *	current implementation for the Mac has most functionality stubbed out.
 *
 *	The current plan, which we have not had time to implement, is for the
 *	first Wish app to create a gestalt of type 'WIsH'. This gestalt will
 *	point to a table, in system memory, of Tk apps. Each Tk app, when it
 *	starts up, will register their name, and process ID, in this table.
 *	This will allow us to implement "tk appname".
 *
 *	Then the send command will look up the process id of the target app in
 *	this table, and send an AppleEvent to that process. The AppleEvent
 *	handler is much like the do script handler, except that you have to
 *	specify the name of the tk app as well, since there may be many
 *	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 <[email protected]>
 * 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 <[email protected]>
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXInt.h"

Changes to macosx/tkMacOSXServices.c.

1
2
3
4
5
6
7
8



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


25
26
27
28
29
30
31
32
33
34
35
1
2
3
4
5



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


23
24
25
26


27
28
29
30
31
32
33





-
-
-
+
+
+














-
-
+
+


-
-







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

/*
 * Event proc which calls the PerformService procedure.
 */

static int
ServicesEventProc(
    Tcl_Event *event,
    int flags)
    TCL_UNUSED(Tcl_Event *),
    TCL_UNUSED(int))
{
    TkMainInfo *info = TkGetMainInfoList();
    (void)event;
    (void)flags;

    Tcl_GlobalEval(info->interp, "::tk::mac::PerformService");
    return 1;
}

/*
 * The Wish application can send the current selection in the Tk clipboard
139
140
141
142
143
144
145
146

147
148
149
150
151
152
153
154
155
137
138
139
140
141
142
143

144
145

146
147
148
149
150
151
152







-
+

-








 * Instantiate a TkService object and register it with the NSApplication.
 * This is called exactly one time from TkpInit.
 */

int
TkMacOSXServices_Init(
    Tcl_Interp *dummy)
    TCL_UNUSED(Tcl_Interp *))
{
    (void)dummy;
    /*
     * Initialize an instance of TkService and register it with the NSApp.
     */

    TkService *service = [[TkService alloc] init];
    [NSApp setServicesProvider:service];
    return TCL_OK;

Changes to macosx/tkMacOSXSubwindows.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





-
-
-
+
+
+








+







/*
 * 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 <[email protected]>
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2006-2009 Daniel A. Steffen <[email protected]>
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXDebug.h"
#include "tkMacOSXWm.h"
#include "tkMacOSXConstants.h"

/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_CLIP_REGIONS
#endif
*/

34
35
36
37
38
39
40
41

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

55
56
57

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

73
74
75
76
77
78
79
35
36
37
38
39
40
41

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

55
56
57

58

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

72
73
74
75
76
77
78
79







-
+












-
+


-
+
-













-
+









/*
 *----------------------------------------------------------------------
 *
 * XDestroyWindow --
 *
 *	Dealocates the given X Window.
 *	Deallocates the given X Window.
 *
 * Results:
 *	The window id is returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
XDestroyWindow(
    Display *display,		/* Display. */
    TCL_UNUSED(Display *),		/* Display. */
    Window window)		/* Window. */
{
    MacDrawable *macWin = (MacDrawable *) window;
    MacDrawable *macWin = (MacDrawable *)window;
    (void)display;

    /*
     * Remove any dangling pointers that may exist if the window we are
     * deleting is being tracked by the grab code.
     */

    TkPointerDeadWindow(macWin->winPtr);
    TkMacOSXSelDeadWindow(macWin->winPtr);
    macWin->toplevel->referenceCount--;

    if (!Tk_IsTopLevel(macWin->winPtr)) {
	TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
	if (macWin->winPtr->parentPtr != NULL) {
	    TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr->parentPtr);
	    TkMacOSXInvalClipRgns((Tk_Window)macWin->winPtr->parentPtr);
	}
	if (macWin->visRgn) {
	    CFRelease(macWin->visRgn);
            macWin->visRgn = NULL;
	}
	if (macWin->aboveVisRgn) {
	    CFRelease(macWin->aboveVisRgn);
116
117
118
119
120
121
122
123
124




125
126
127

128
129
130



131
132
133
134
135
136
137
138
139



140

141
142

143

144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160

161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177








178
179
180
181
182
183
184
185
186
187

188
189
190
191

192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

214
215


216
217



218
219



220
221
222
223
224
225


226
227
228
229
230








231
232
233
234
235
236
237
116
117
118
119
120
121
122


123
124
125
126
127
128

129
130
131

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

147
148

149

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172
173
174
175
176
177
178






179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195

196
197
198


199














200
201
202
203
204
205
206

207
208
209
210
211


212
213
214


215
216
217
218
219
220
221
222
223
224
225





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







-
-
+
+
+
+


-
+


-
+
+
+









+
+
+
-
+

-
+
-
+














-


+











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









-
+


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







-
+


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






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







}

/*
 *----------------------------------------------------------------------
 *
 * XMapWindow --
 *
 *	Map the given X Window to the screen. See X window documentation for
 *	more details.
 *	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:
 *	None.
 *	Returns Success or BadWindow.
 *
 * Side effects:
 *	The subwindow or toplevel may appear on the screen.
 *	The subwindow or toplevel may appear on the screen.  VisibilityNotify
 *      events are generated.
 *
 *
 *----------------------------------------------------------------------
 */

int
XMapWindow(
    Display *display,		/* Display. */
    Window window)		/* Window. */
{
    if (!window) {
	return BadWindow;
    }
    MacDrawable *macWin = (MacDrawable *) window;
    MacDrawable *macWin = (MacDrawable *)window;
    TkWindow *winPtr = macWin->winPtr;
    NSWindow *win = TkMacOSXDrawableWindow(window);
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(window);
    XEvent event;
    static Bool initialized = NO;

    /*
     * Under certain situations it's possible for this function to be called
     * before the toplevel window it's associated with has actually been
     * mapped. In that case we need to create the real Macintosh window now as
     * this function as well as other X functions assume that the portPtr is
     * valid.
     */

    if (!TkMacOSXHostToplevelExists(macWin->toplevel->winPtr)) {
	TkMacOSXMakeRealWindowExist(macWin->toplevel->winPtr);
    }

    display->request++;
    winPtr->flags |= TK_MAPPED;
    if (Tk_IsTopLevel(winPtr)) {
	if (!Tk_IsEmbedded(winPtr)) {
	    TKContentView *view = [win contentView];

	    /*
	     * We want to activate Tk when a toplevel is mapped but we must not
	     * supply YES here.  This is because during Tk initialization the
	     * root window is mapped before applicationDidFinishLaunching
	     * returns. Forcing the app to activate too early can make the menu
	     * bar unresponsive.
	     */

	    TkMacOSXApplyWindowAttributes(winPtr, win);
	    [win setExcludedFromWindowsMenu:NO];
	    [NSApp activateIgnoringOtherApps:NO];
	    [[win contentView] setNeedsDisplay:YES];
	    if ([win canBecomeKeyWindow]) {
		[win makeKeyAndOrderFront:NSApp];
	    } else {
		[win orderFrontRegardless];
	    [NSApp activateIgnoringOtherApps:initialized];
	    [view addTkDirtyRect: [view bounds]];
	    if (initialized) {
		if ([win canBecomeKeyWindow]) {
		    [win makeKeyAndOrderFront:NSApp];
		} else {
		    [win orderFrontRegardless];
		}
	    }
	} else {
	    TkWindow *contWinPtr = TkpGetOtherWindow(winPtr);

	    /*
	     * Rebuild the container's clipping region and display
	     * the window.
	     */

	    TkMacOSXInvalClipRgns((Tk_Window) contWinPtr);
	    TkMacOSXInvalClipRgns((Tk_Window)contWinPtr);
	    TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
	}

	TkMacOSXInvalClipRgns((Tk_Window) winPtr);
	TkMacOSXInvalClipRgns((Tk_Window)winPtr);

	/*
	 * We only need to send the MapNotify event for toplevel windows.
	 */

	event.xany.serial = LastKnownRequestProcessed(display);
	event.xany.send_event = False;
	event.xany.display = display;

	event.xmap.window = window;
	event.xmap.type = MapNotify;
	event.xmap.event = window;
	event.xmap.override_redirect = winPtr->atts.override_redirect;
	Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
    } else {

	/*
	 * For non-toplevel windows, rebuild the parent's clipping region
	 * and redisplay the window.
	 */

	TkMacOSXInvalClipRgns((Tk_Window) winPtr->parentPtr);
	TkMacOSXInvalClipRgns((Tk_Window)winPtr->parentPtr);
    }

    /*
     * Mark the toplevel as needing to be redrawn, unless the window is being
    if ([NSApp isDrawing]) {
	[[win contentView] setNeedsRedisplay:YES];
     * mapped while drawing is taking place.
     */

    } else {
	[[win contentView] setNeedsDisplay:YES];
    TKContentView *view = [win contentView];
    if (view != [NSView focusView]) {
	[view addTkDirtyRect:[view bounds]];
    }

    /*
     * Generate VisibilityNotify events for window and all mapped children.
     */

    if (initialized) {
	XEvent event;
    event.xany.send_event = False;
    event.xany.display = display;
    event.xvisibility.type = VisibilityNotify;
    event.xvisibility.state = VisibilityUnobscured;
    NotifyVisibility(winPtr, &event);
	event.xany.send_event = False;
	event.xany.display = display;
	event.xvisibility.type = VisibilityNotify;
	event.xvisibility.state = VisibilityUnobscured;
	NotifyVisibility(winPtr, &event);
    } else {
	initialized = YES;
    }
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * NotifyVisibility --
266
267
268
269
270
271
272
273
274




275
276
277

278
279
280
281
282
283
284
285
286
287
288
289
290

291
292
293
294
295





296
297
298
299
300

301
302

303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326

327
328
329

330
331
332
333
334

335
336


337
338
339
340
341
342
343
269
270
271
272
273
274
275


276
277
278
279
280
281

282
283
284
285
286
287
288
289
290
291
292
293
294

295
296
297



298
299
300
301
302
303
304
305
306
307
308
309

310














311
312
313
314
315
316
317
318
319

320
321
322

323
324
325



326


327
328
329
330
331
332
333
334
335







-
-
+
+
+
+


-
+












-
+


-
-
-
+
+
+
+
+





+

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









-
+


-
+


-
-
-
+
-
-
+
+







}

/*
 *----------------------------------------------------------------------
 *
 * XUnmapWindow --
 *
 *	Unmap the given X Window to the screen. See X window documentation for
 *	more details.
 *	This X11 stub maps the given X11 Window but does not update any of
 *	The Tk structures describing the window.  Tk applications should
 *	never call this directly, but it is called by Tk_UnmapWindow and
 *      Tk_WmUnmapWindow.
 *
 * Results:
 *	None.
 *	Always returns Success or BadWindow.
 *
 * Side effects:
 *	The subwindow or toplevel may be removed from the screen.
 *
 *----------------------------------------------------------------------
 */

int
XUnmapWindow(
    Display *display,		/* Display. */
    Window window)		/* Window. */
{
    MacDrawable *macWin = (MacDrawable *) window;
    MacDrawable *macWin = (MacDrawable *)window;
    TkWindow *winPtr = macWin->winPtr;
    TkWindow *parentPtr = winPtr->parentPtr;
    NSWindow *win = TkMacOSXDrawableWindow(window);
    XEvent event;

    NSWindow *win = TkMacOSXGetNSWindowForDrawable(window);

    if (!window) {
	return BadWindow;
    }
    display->request++;
    if (Tk_IsTopLevel(winPtr)) {
	if (!Tk_IsEmbedded(winPtr) &&
		winPtr->wmInfoPtr->hints.initial_state!=IconicState) {
	    [win orderOut:nil];
	    [win setExcludedFromWindowsMenu:YES];
	}
	TkMacOSXInvalClipRgns((Tk_Window) winPtr);
	TkMacOSXInvalClipRgns((Tk_Window)winPtr);

	/*
	 * We only need to send the UnmapNotify event for toplevel windows.
	 */

	event.xany.serial = LastKnownRequestProcessed(display);
	event.xany.send_event = False;
	event.xany.display = display;

	event.xunmap.type = UnmapNotify;
	event.xunmap.window = window;
	event.xunmap.event = window;
	event.xunmap.from_configure = false;
	Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
    } else {
	/*
	 * Rebuild the visRgn clip region for the parent so it will be allowed
	 * to draw in the space from which this subwindow was removed and then
	 * redraw the window.
	 */

	if (parentPtr && parentPtr->privatePtr->visRgn) {
	    TkMacOSXInvalidateViewRegion(
		    TkMacOSXDrawableView(parentPtr->privatePtr),
		    TkMacOSXGetNSViewForDrawable(parentPtr->privatePtr),
		    parentPtr->privatePtr->visRgn);
	}
	TkMacOSXInvalClipRgns((Tk_Window) parentPtr);
	TkMacOSXInvalClipRgns((Tk_Window)parentPtr);
	TkMacOSXUpdateClipRgn(parentPtr);
    }
    winPtr->flags &= ~TK_MAPPED;
    if ([NSApp isDrawing]) {
	[[win contentView] setNeedsRedisplay:YES];
    TKContentView *view = [win contentView];
    } else {
	[[win contentView] setNeedsDisplay:YES];
    if (view != [NSView focusView]) {
	[view addTkDirtyRect:[view bounds]];
    }
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
358
359
360
361
362
363
364
365

366
367
368
369

370
371



372

373
374
375
376
377





378
379
380
381
382
383
384
350
351
352
353
354
355
356

357
358
359
360

361
362
363
364
365
366

367
368




369
370
371
372
373
374
375
376
377
378
379
380







-
+



-
+


+
+
+
-
+

-
-
-
-
+
+
+
+
+







int
XResizeWindow(
    Display *display,		/* Display. */
    Window window,		/* Window. */
    unsigned int width,
    unsigned int height)
{
    MacDrawable *macWin = (MacDrawable *) window;
    MacDrawable *macWin = (MacDrawable *)window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	NSWindow *w = macWin->winPtr->wmInfoPtr->window;
	TKWindow *w = (TKWindow *)macWin->winPtr->wmInfoPtr->window;

	if (w) {
	    if ([w styleMask] & NSFullScreenWindowMask) {
		[w tkLayoutChanged];
	    } else {
	    NSRect r = [w contentRectForFrameRect:[w frame]];
		NSRect r = [w contentRectForFrameRect:[w frame]];

	    r.origin.y += r.size.height - height;
	    r.size.width = width;
	    r.size.height = height;
	    [w setFrame:[w frameRectForContentRect:r] display:YES];
		r.origin.y += r.size.height - height;
		r.size.width = width;
		r.size.height = height;
		[w setFrame:[w frameRectForContentRect:r] display:NO];
	    }
	}
    } else {
	MoveResizeWindow(macWin);
    }
    return Success;
}

403
404
405
406
407
408
409
410

411
412
413
414
415
416
417
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413







-
+







XMoveResizeWindow(
    Display *display,		/* Display. */
    Window window,		/* Window. */
    int x, int y,
    unsigned int width,
    unsigned int height)
{
    MacDrawable *macWin = (MacDrawable *) window;
    MacDrawable *macWin = (MacDrawable *)window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	NSWindow *w = macWin->winPtr->wmInfoPtr->window;

	if (w) {
	    /*
426
427
428
429
430
431
432
433

434
435
436
437
438
439
440
422
423
424
425
426
427
428

429
430
431
432
433
434
435
436







-
+







	    CGFloat Height = (CGFloat) height;
	    CGFloat XOff = (CGFloat) macWin->winPtr->wmInfoPtr->xInParent;
	    CGFloat YOff = (CGFloat) macWin->winPtr->wmInfoPtr->yInParent;
	    NSRect r = NSMakeRect(
		    X + XOff, TkMacOSXZeroScreenHeight() - Y - YOff - Height,
	    	    Width, Height);

	    [w setFrame:[w frameRectForContentRect:r] display:YES];
	    [w setFrame:[w frameRectForContentRect:r] display:NO];
	}
    } else {
	MoveResizeWindow(macWin);
    }
    return Success;
}

456
457
458
459
460
461
462
463

464
465
466
467
468
469
470
452
453
454
455
456
457
458

459
460
461
462
463
464
465
466







-
+








int
XMoveWindow(
    Display *display,		/* Display. */
    Window window,		/* Window. */
    int x, int y)
{
    MacDrawable *macWin = (MacDrawable *) window;
    MacDrawable *macWin = (MacDrawable *)window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	NSWindow *w = macWin->winPtr->wmInfoPtr->window;

	if (w) {
	    [w setFrameTopLeftPoint: NSMakePoint(
494
495
496
497
498
499
500
501

502
503
504
505
506
507
508
490
491
492
493
494
495
496

497
498
499
500
501
502
503
504







-
+








static void
MoveResizeWindow(
    MacDrawable *macWin)
{
    int deltaX = 0, deltaY = 0, parentBorderwidth = 0;
    MacDrawable *macParent = NULL;
    NSWindow *macWindow = TkMacOSXDrawableWindow((Drawable) macWin);
    NSWindow *macWindow = TkMacOSXGetNSWindowForDrawable((Drawable)macWin);

    /*
     * Find the Parent window, for an embedded window it will be its container.
     */

    if (Tk_IsEmbedded(macWin->winPtr)) {
	TkWindow *contWinPtr = TkpGetOtherWindow(macWin->winPtr);
531
532
533
534
535
536
537
538

539
540
541
542
543
544
545
527
528
529
530
531
532
533

534
535
536
537
538
539
540
541







-
+







		macWin->winPtr->changes.x - macWin->xOff;
	deltaY = macParent->yOff + parentBorderwidth +
		macWin->winPtr->changes.y - macWin->yOff;
    }
    if (macWindow) {
	TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
	if (macParent) {
	    TkMacOSXInvalClipRgns((Tk_Window) macParent->winPtr);
	    TkMacOSXInvalClipRgns((Tk_Window)macParent->winPtr);
	}
    }
    UpdateOffsets(macWin->winPtr, deltaX, deltaY);
    if (macWindow) {
	TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
    }
    GenerateConfigureNotify(macWin->winPtr, 0);
599
600
601
602
603
604
605
606

607
608
609
610
611
612
613
595
596
597
598
599
600
601

602
603
604
605
606
607
608
609







-
+







 */

int
XRaiseWindow(
    Display *display,		/* Display. */
    Window window)		/* Window. */
{
    MacDrawable *macWin = (MacDrawable *) window;
    MacDrawable *macWin = (MacDrawable *)window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	TkWmRestackToplevel(macWin->winPtr, Above, NULL);
    } else {
	/*
	 * TODO: this should generate damage
633
634
635
636
637
638
639
640

641
642
643
644
645
646
647
629
630
631
632
633
634
635

636
637
638
639
640
641
642
643







-
+







 */

int
XLowerWindow(
    Display *display,		/* Display. */
    Window window)		/* Window. */
{
    MacDrawable *macWin = (MacDrawable *) window;
    MacDrawable *macWin = (MacDrawable *)window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	TkWmRestackToplevel(macWin->winPtr, Below, NULL);
    } else {
	/*
	 * TODO: this should generate damage
669
670
671
672
673
674
675
676

677
678

679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701

702
703
704
705


706
707
708
709
710
711
712
665
666
667
668
669
670
671

672
673

674
675

676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695

696
697
698


699
700
701
702
703
704
705
706
707







-
+

-
+

-




















-
+


-
-
+
+







 */

int
XConfigureWindow(
    Display *display,		/* Display. */
    Window w,			/* Window. */
    unsigned int value_mask,
    XWindowChanges *values)
    TCL_UNUSED(XWindowChanges *))
{
    MacDrawable *macWin = (MacDrawable *) w;
    MacDrawable *macWin = (MacDrawable *)w;
    TkWindow *winPtr = macWin->winPtr;
    (void)values;

    display->request++;

    /*
     * 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,
		winPtr->changes.width, winPtr->changes.height);
    }

    /*
     * Change the stacking order of the window. Tk actually keeps all the
     * information we need for stacking order. All we need to do is make sure
     * the clipping regions get updated and generate damage that will ensure
     * things get drawn correctly.
     */

    if (value_mask & CWStackMode) {
	NSView *view = TkMacOSXDrawableView(macWin);
	NSView *view = TkMacOSXGetNSViewForDrawable(macWin);

	if (view) {
	    TkMacOSXInvalClipRgns((Tk_Window) winPtr->parentPtr);
	    TkpRedrawWidget((Tk_Window) winPtr);
	    TkMacOSXInvalClipRgns((Tk_Window)winPtr->parentPtr);
	    TkpRedrawWidget((Tk_Window)winPtr);
	}
    }

#if 0
    TkGenWMMoveRequestEvent(macWin->winPtr,
	    macWin->winPtr->changes.x, macWin->winPtr->changes.y);
#endif
817
818
819
820
821
822
823
824

825
826
827
828
829
830
831
812
813
814
815
816
817
818

819
820
821
822
823
824
825
826







-
+







	     */

	    TkMacOSXWinCGBounds(winPtr, &bounds);
	    rgn = TkMacOSXHIShapeCreateMutableWithRect(&bounds);

	    /*
	     * Clip away the area of any windows that may obscure this window.
	     * For a non-toplevel window, first, clip to the parents visible
	     * For a non-toplevel window, first, clip to the parent's visible
	     * clip region. Second, clip away any siblings that are higher in
	     * the stacking order. For an embedded toplevel, just clip to the
	     * container's visible clip region. Remember, we only allow one
	     * contained window in a frame, and don't support any other widgets
	     * in the frame either. This is not currently enforced, however.
	     */

846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
841
842
843
844
845
846
847









848
849
850
851
852
853
854







-
-
-
-
-
-
-
-
-







		}
	    } else if (Tk_IsEmbedded(winPtr)) {
		win2Ptr = TkpGetOtherWindow(winPtr);
		if (win2Ptr) {
		    TkMacOSXUpdateClipRgn(win2Ptr);
		    ChkErr(HIShapeIntersect,
			    win2Ptr->privatePtr->aboveVisRgn, rgn, rgn);
		} else if (tkMacOSXEmbedHandler != NULL) {
		    Region r = XCreateRegion();
		    HIShapeRef visRgn;

		    tkMacOSXEmbedHandler->getClipProc((Tk_Window) winPtr, r);
		    visRgn = TkMacOSXGetNativeRegion(r);
		    ChkErr(HIShapeIntersect, visRgn, rgn, rgn);
		    CFRelease(visRgn);
		    TkpReleaseRegion(r);
		}

		/*
		 * TODO: Here we should handle out of process embedding.
		 */
	    }
	    macWin->aboveVisRgn = HIShapeCreateCopy(rgn);
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
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







-
+




-
-
+
+










-
-
+
+







 *
 *----------------------------------------------------------------------
 */

static OSStatus
InvalViewRect(
    int msg,
    HIShapeRef rgn,
    TCL_UNUSED(HIShapeRef),
    const CGRect *rect,
    void *ref)
{
    static CGAffineTransform t;
    NSView *view = ref;
    (void)rgn;
    TKContentView *view = ref;
    NSRect dirtyRect;

    if (!view) {
	return paramErr;
    }
    switch (msg) {
    case kHIShapeEnumerateInit:
	t = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0,
		NSHeight([view bounds]));
	break;
    case kHIShapeEnumerateRect:
	[view setNeedsDisplayInRect:NSRectFromCGRect(
		CGRectApplyAffineTransform(*rect, t))];
	dirtyRect = NSRectFromCGRect(CGRectApplyAffineTransform(*rect, t));
	[view addTkDirtyRect:dirtyRect];
	break;
    }
    return noErr;
}

void
TkMacOSXInvalidateViewRegion(
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
1028
1029
1030
1031
1032
1033
1034

1035
1036
1037
1038
1039
1040
1041

1042
1043

1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055


1056
1057
1058
1059

1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075






1076

































































1077
1078
1079
1080
1081
1082
1083
1084
1085
1086

1087
1088
1089
1090
1091
1092

1093
1094
1095
1096

1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108





1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132







-
+






-
+

-
+
+










-
-
+
+


-
+















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








+
+
-
+
+
+
+
+

-
+
+


-
+











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







{
#ifdef TK_MAC_DEBUG_CLIP_REGIONS
    TkMacOSXDbgMsg("%s", macWin->winPtr->pathName);
#endif
    if (macWin->flags & TK_CLIP_INVALID) {
	TkMacOSXUpdateClipRgn(macWin->winPtr);
    }
    TkMacOSXInvalidateViewRegion(TkMacOSXDrawableView(macWin),
    TkMacOSXInvalidateViewRegion(TkMacOSXGetNSViewForDrawable(macWin),
	    (flag == TK_WINDOW_ONLY) ? macWin->visRgn : macWin->aboveVisRgn);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXDrawableWindow --
 * TkMacOSXGetNSWindowForDrawable --
 *
 *	This function returns the NSWindow for a given X drawable.
 *	This function returns the NSWindow for a given X drawable, if the
 *      drawable is a window.  If the drawable is a pixmap it returns nil.
 *
 * Results:
 *	A NSWindow, or nil for off screen pixmaps.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

NSWindow *
TkMacOSXDrawableWindow(
void *
Tk_MacOSXGetNSWindowForDrawable(
    Drawable drawable)
{
    MacDrawable *macWin = (MacDrawable *) drawable;
    MacDrawable *macWin = (MacDrawable *)drawable;
    NSWindow *result = nil;

    if (!macWin || macWin->flags & TK_IS_PIXMAP) {
	result = nil;
    } else if (macWin->toplevel && macWin->toplevel->winPtr &&
	    macWin->toplevel->winPtr->wmInfoPtr &&
	    macWin->toplevel->winPtr->wmInfoPtr->window) {
	result = macWin->toplevel->winPtr->wmInfoPtr->window;
    } else if (macWin->winPtr && macWin->winPtr->wmInfoPtr &&
	    macWin->winPtr->wmInfoPtr->window) {
	result = macWin->winPtr->wmInfoPtr->window;
    } else if (macWin->toplevel && (macWin->toplevel->flags & TK_EMBEDDED)) {
	TkWindow *contWinPtr = TkpGetOtherWindow(macWin->toplevel->winPtr);

	if (contWinPtr) {
	    result = TkMacOSXDrawableWindow((Drawable) contWinPtr->privatePtr);
	}
    }
    return result;
}

	    result = TkMacOSXGetNSWindowForDrawable((Drawable)contWinPtr->privatePtr);
void *
TkMacOSXDrawable(
    Drawable drawable)
{
    return TkMacOSXDrawableWindow(drawable);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetDrawablePort --
 *
 *	This function returns the Graphics Port for a given X drawable.
 *
 * Results:
 *	NULL.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void *
TkMacOSXGetDrawablePort(
    Drawable drawable)
{
    (void)drawable;

    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXDrawableView --
 *
 *	This function returns the NSView for a given X drawable.
 *
 * Results:
 *	A NSView* or nil.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

NSView *
TkMacOSXDrawableView(
    MacDrawable *macWin)
{
    NSView *result = nil;

    if (!macWin) {
	result = nil;
    } else if (!macWin->toplevel) {
	result = macWin->view;
    } else if (!(macWin->toplevel->flags & TK_EMBEDDED)) {
	result = macWin->toplevel->view;
    } else {
	TkWindow *contWinPtr = TkpGetOtherWindow(macWin->toplevel->winPtr);

	if (contWinPtr) {
	    result = TkMacOSXDrawableView(contWinPtr->privatePtr);
	}
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetNSViewForDrawable/TkMacOSXGetRootControl --
 *
 * TkMacOSXGetRootControl --
 *	The function name TkMacOSXGetRootControl is being preserved only
 *      because it exists in a stubs table.  Nobody knows what it means to
 *      get a "RootControl".  The macro TkMacOSXGetNSViewForDrawable calls
 *      this function and should always be used rather than directly using
 *      the obscure official name of this function.
 *
 *	This function returns the NSView for a given X drawable.
 *      It returns the NSView for a given X drawable in the case that the
 *      drawable is a window.  If the drawable is a pixmap it returns nil.
 *
 * Results:
 *	A NSView* .
 *	A NSView* or nil.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void *
TkMacOSXGetRootControl(
    Drawable drawable)
{
    /*
     * will probably need to fix this up for embedding
     */

    return TkMacOSXDrawableView((MacDrawable *) drawable);
    void *result = NULL;
    MacDrawable *macWin = (MacDrawable *)drawable;

    if (!macWin) {
	result = NULL;
    } else if (!macWin->toplevel) {
	result = macWin->view;
    } else if (!(macWin->toplevel->flags & TK_EMBEDDED)) {
	result = macWin->toplevel->view;
    } else {
	TkWindow *contWinPtr = TkpGetOtherWindow(macWin->toplevel->winPtr);

	if (contWinPtr) {
	    result = TkMacOSXGetRootControl((Drawable)contWinPtr->privatePtr);
	}
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXInvalClipRgns --
 *
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
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







-
+












-
+













-
+








-
+







     * Invalidate clip regions for all children & their descendants, unless the
     * child is a toplevel.
     */

    childPtr = winPtr->childList;
    while (childPtr) {
	if (!Tk_IsTopLevel(childPtr)) {
	    TkMacOSXInvalClipRgns((Tk_Window) childPtr);
	    TkMacOSXInvalClipRgns((Tk_Window)childPtr);
	}
	childPtr = childPtr->nextPtr;
    }

    /*
     * Also, if the window is a container, mark its embedded window.
     */

    if (Tk_IsContainer(winPtr)) {
	childPtr = TkpGetOtherWindow(winPtr);

	if (childPtr) {
	    TkMacOSXInvalClipRgns((Tk_Window) childPtr);
	    TkMacOSXInvalClipRgns((Tk_Window)childPtr);
	}

	/*
	 * TODO: Here we should handle out of process embedding.
	 */
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXWinBounds --
 *
 *	Given a Tk window this function determines the windows bounds in
 *	Given a Tk window this function determines the window's bounds in
 *	relation to the Macintosh window's coordinate system. This is also the
 *	same coordinate system as the Tk toplevel window in which this window
 *	is contained.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *	Fills in a Rect.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXWinBounds(
    TkWindow *winPtr,
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
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







-
+
-
-
-
+
+





-
+














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







}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXWinCGBounds --
 *
 *	Given a Tk window this function determines the windows bounds in
 *	Given a Tk window this function determines the window's bounds in
 *	relation to the Macintosh window's coordinate system. This is also the
 *	same coordinate system as the Tk toplevel window in which this window
 *	is contained.
 *	the coordinate system of the Tk toplevel window in which this window
 *	is contained.  This fills in a CGRect struct.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *	Fill in a CGRect.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXWinCGBounds(
    TkWindow *winPtr,
    CGRect *bounds)
{
    bounds->origin.x = winPtr->privatePtr->xOff;
    bounds->origin.y = winPtr->privatePtr->yOff;
    bounds->size.width = winPtr->changes.width;
    bounds->size.height = winPtr->changes.height;
}
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXWinNSBounds --
 *
 *	Given a Tk window this function determines the window's bounds in
 *	the coordinate system of the TKContentView in which this Tk window
 *	is contained, which has the origin at the lower left corner.  This
 *      fills in an NSRect struct and requires the TKContentView as a
 *      parameter
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Fills in an NSRect.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXWinNSBounds(
    TkWindow *winPtr,
    NSView *view,
    NSRect *bounds)
{
    bounds->size.width = winPtr->changes.width;
    bounds->size.height = winPtr->changes.height;
    bounds->origin.x = winPtr->privatePtr->xOff;
    bounds->origin.y = ([view bounds].size.height -
		       bounds->size.height -
		       winPtr->privatePtr->yOff);
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateOffsets --
 *
 *	Updates the X & Y offsets of the given TkWindow from the TopLevel it is
1411
1412
1413
1414
1415
1416
1417
1418

1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1379
1380
1381
1382
1383
1384
1385

1386
1387
1388
1389
1390
1391

1392
1393
1394
1395
1396
1397
1398







-
+





-







 *
 *----------------------------------------------------------------------
 */

Pixmap
Tk_GetPixmap(
    Display *display,	/* Display for new pixmap (can be null). */
    Drawable d,		/* Drawable where pixmap will be used (ignored). */
    TCL_UNUSED(Drawable),		/* Drawable where pixmap will be used (ignored). */
    int width,		/* Dimensions of pixmap. */
    int height,
    int depth)		/* Bits per pixel for pixmap. */
{
    MacDrawable *macPix;
    (void)d;

    if (display != NULL) {
	display->request++;
    }
    macPix = (MacDrawable *)ckalloc(sizeof(MacDrawable));
    macPix->winPtr = NULL;
    macPix->xOff = 0;
1460
1461
1462
1463
1464
1465
1466
1467

1468
1469
1470
1471
1472
1473
1474
1427
1428
1429
1430
1431
1432
1433

1434
1435
1436
1437
1438
1439
1440
1441







-
+







 */

void
Tk_FreePixmap(
    Display *display,		/* Display. */
    Pixmap pixmap)		/* Pixmap to destroy */
{
    MacDrawable *macPix = (MacDrawable *) pixmap;
    MacDrawable *macPix = (MacDrawable *)pixmap;

    display->request++;
    if (macPix->context) {
	char *data = CGBitmapContextGetData(macPix->context);

	if (data) {
	    ckfree(data);

Added macosx/tkMacOSXSysTray.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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
 * tkMacOSXSysTray.c --
 *
 *	tkMacOSXSysTray.c implements a "systray" Tcl command which allows
 *      one to change the system tray/taskbar icon of a Tk toplevel
 *      window and a "sysnotify" command to post system notifications.
 *      In macOS the icon appears on the right hand side of the menu bar.
 *
 * Copyright © 2020 Kevin Walzer/WordTech Communications LLC.
 * Copyright © 2020 Jan Nijtmans.
 * 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 <tkInt.h>
#include <tkMacOSXInt.h>
#include "tkMacOSXPrivate.h"

/*
 * Prior to macOS 10.14 user notifications were handled by the NSApplication's
 * NSUserNotificationCenter via a NSUserNotificationCenterDelegate object.
 * These classes were defined in the CoreFoundation framework.  In macOS 10.14
 * a separate UserNotifications framework was introduced which adds some
 * additional features, including custom controls on the notification window
 * but primarily a requirement that an application must be authorized before
 * being allowed to post a notification.  This framework uses a different
 * class, the UNUserNotificationCenter, and its delegate follows a different
 * protocol, named UNUserNotificationCenterDelegate.
 *
 * In macOS 11.0 the NSUserNotificationCenter and its delegate protocol were
 * deprecated.  To make matters more complicated, it turns out that there is a
 * secret undocumented additional requirement that an app which is not signed
 * can never be authorized to send notifications via the UNNotificationCenter.
 * (As of 11.0, it appears that it is sufficient to sign the app with a
 * self-signed certificate, however.)
 *
 * The workaround implemented here is to define two classes, TkNSNotifier and
 * TkUNNotifier, each of which provides one of these protocols on macOS 10.14
 * and newer.  If the TkUSNotifier is able to obtain authorization it is used.
 * Otherwise, TkNSNotifier is used.  Building TkNSNotifier on 11.0 or later
 * produces deprecation warnings which are suppressed by enclosing the
 * interface and implementation in #pragma blocks.  The first time that the tk
 * systray command in initialized in an interpreter an attempt is made to
 * obtain authorization for sending notifications with the UNNotificationCenter
 * on systems and the result is saved in a static variable.
 */

//#define DEBUG
#ifdef DEBUG

/*
 * This macro uses the do ... while(0) trick to swallow semicolons.  It logs to
 * a temp file because apps launched from an icon have no stdout or stderr and
 * because NSLog has a tendency to not produce any console messages at certain
 * stages of launching an app.
 */

#define DEBUG_LOG(format, ...)                \
    do {				      \
    FILE* logfile = fopen("/tmp/tklog", "a"); \
    fprintf(logfile, format, ##__VA_ARGS__);  \
    fflush(logfile);                          \
    fclose(logfile); } while (0)
#else
#define DEBUG_LOG(format, ...)
#endif

#define BUILD_TARGET_HAS_NOTIFICATION (MAC_OS_X_VERSION_MAX_ALLOWED >= 101000)
#define BUILD_TARGET_HAS_UN_FRAMEWORK (MAC_OS_X_VERSION_MAX_ALLOWED >= 101400)
#if MAC_OS_X_VERSION_MAX_ALLOWED > 101500
#define ALERT_OPTION  UNNotificationPresentationOptionList | \
    		      UNNotificationPresentationOptionBanner
#else
#define ALERT_OPTION  UNNotificationPresentationOptionAlert
#endif

#if BUILD_TARGET_HAS_UN_FRAMEWORK
#import <UserNotifications/UserNotifications.h>
static NSString *TkNotificationCategory;
#endif

#if BUILD_TARGET_HAS_NOTIFICATION

/*
 * Class declaration for TkStatusItem.
 */

@interface TkStatusItem: NSObject {
    NSStatusItem * statusItem;
    NSStatusBar * statusBar;
    NSImage * icon;
    NSString * tooltip;
    Tcl_Interp * interp;
    Tcl_Obj * b1_callback;
    Tcl_Obj * b3_callback;
}

- (id) init : (Tcl_Interp *) interp;
- (void) setImagewithImage : (NSImage *) image;
- (void) setTextwithString : (NSString *) string;
- (void) setB1Callback : (Tcl_Obj *) callback;
- (void) setB3Callback : (Tcl_Obj *) callback;
- (void) clickOnStatusItem;
- (void) dealloc;

@end

/*
 * Class declaration for TkNSNotifier. A TkNSNotifier object has no attributes
 * but implements the NSUserNotificationCenterDelegate protocol.  It also has
 * one additional method which posts a user notification. There is one
 * TkNSNotifier for the application, shared by all interpreters.
 */

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
@interface TkNSNotifier: NSObject {
}

/*
 * Post a notification.
 */

- (void) postNotificationWithTitle : (NSString *) title message: (NSString *) detail;

/*
 * The following methods comprise the NSUserNotificationCenterDelegate protocol.
 */

- (void) userNotificationCenter:(NSUserNotificationCenter *)center
    didDeliverNotification:(NSUserNotification *)notification;

- (void) userNotificationCenter:(NSUserNotificationCenter *)center
    didActivateNotification:(NSUserNotification *)notification;

- (BOOL) userNotificationCenter:(NSUserNotificationCenter *)center
    shouldPresentNotification:(NSUserNotification *)notification;

@end
#pragma clang diagnostic pop

/*
 * The singleton instance of TkNSNotifier shared by all interpreters in this
 * application.
 */

static TkNSNotifier *NSnotifier = nil;

#if BUILD_TARGET_HAS_UN_FRAMEWORK

/*
 * Class declaration for TkUNNotifier. A TkUNNotifier object has no attributes
 * but implements the UNUserNotificationCenterDelegate protocol It also has two
 * additional methods.  One requests authorization to post notification via the
 * UserNotification framework and the other posts a user notification. There is
 * at most one TkUNNotifier for the application, shared by all interpreters.
 */

@interface TkUNNotifier: NSObject {
}

 /*
 * Request authorization to post a notification.
 */

- (void) requestAuthorization;

/*
 * Post a notification.
 */

- (void) postNotificationWithTitle : (NSString *) title message: (NSString *) detail;

/*
 * The following methods comprise the UNNotificationCenterDelegate protocol:
 */

- (void)userNotificationCenter:(UNUserNotificationCenter *)center
    didReceiveNotificationResponse:(UNNotificationResponse *)response
    withCompletionHandler:(void (^)(void))completionHandler;

- (void)userNotificationCenter:(UNUserNotificationCenter *)center
    willPresentNotification:(UNNotification *)notification
    withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler;

- (void)userNotificationCenter:(UNUserNotificationCenter *)center
   openSettingsForNotification:(UNNotification *)notification;

@end

/*
 * The singleton instance of TkUNNotifier shared by all interpeters is stored
 * in this static variable.
 */

static TkUNNotifier *UNnotifier = nil;

#endif

/*
 * Class declaration for TkStatusItem. A TkStatusItem represents an icon posted
 * on the status bar located on the right side of the MenuBar.  Each interpreter
 * may have at most one TkStatusItem.  A pointer to the TkStatusItem belonging
 * to an interpreter is stored as the clientData of the MacSystrayObjCmd instance
 * in that interpreter.  It will be NULL until the tk systray command is executed
 * by the interpreter.
 */

@implementation TkStatusItem : NSObject

- (id) init : (Tcl_Interp *) interpreter {
    [super init];
    statusBar = [NSStatusBar systemStatusBar];
    statusItem = [[statusBar statusItemWithLength:NSVariableStatusItemLength] retain];
    statusItem.button.target = self;
    statusItem.button.action = @selector(clickOnStatusItem);
    [statusItem.button sendActionOn : NSEventMaskLeftMouseUp | NSEventMaskRightMouseUp];
    statusItem.visible = YES;
    interp = interpreter;
    b1_callback = NULL;
    b3_callback = NULL;
    return self;
}

- (void) setImagewithImage : (NSImage *) image
{
    icon = nil;
    icon = image;
    statusItem.button.image = icon;
}

- (void) setTextwithString : (NSString *) string
{
    tooltip = nil;
    tooltip = string;
    statusItem.button.toolTip = tooltip;
}

- (void) setB1Callback : (Tcl_Obj *) obj
{
    if (obj != NULL) {
	Tcl_IncrRefCount(obj);
    }
    if (b1_callback != NULL) {
	Tcl_DecrRefCount(b1_callback);
    }
    b1_callback = obj;
}

- (void) setB3Callback : (Tcl_Obj *) obj
{
    if (obj != NULL) {
	Tcl_IncrRefCount(obj);
    }
    if (b3_callback != NULL) {
	Tcl_DecrRefCount(b3_callback);
    }
    b3_callback = obj;
}

- (void) clickOnStatusItem
{
    NSEvent *event = [NSApp currentEvent];
    if (([event type] == NSEventTypeLeftMouseUp) && (b1_callback != NULL)) {
	int result = Tcl_EvalObjEx(interp, b1_callback, TCL_EVAL_GLOBAL);
	if (result != TCL_OK) {
	    Tcl_BackgroundException(interp, result);
	}
    } else {
	if (([event type] == NSEventTypeRightMouseUp) && (b3_callback != NULL)) {
	    int result = Tcl_EvalObjEx(interp, b3_callback, TCL_EVAL_GLOBAL);
	    if (result != TCL_OK) {
		Tcl_BackgroundException(interp, result);
	    }
	}
    }
}
- (void) dealloc
{
    [statusBar removeStatusItem: statusItem];
    if (b1_callback != NULL) {
	Tcl_DecrRefCount(b1_callback);
    }
    if (b3_callback != NULL) {
	Tcl_DecrRefCount(b3_callback);
    }
    [super dealloc];
}

@end

/*
 * Type used for the ClientData of a MacSystrayObjCmd instance.
 */

typedef TkStatusItem** StatusItemInfo;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
@implementation TkNSNotifier : NSObject

-  (void) postNotificationWithTitle : (NSString * ) title
			     message: (NSString * ) detail
{
    NSUserNotification *notification;
    NSUserNotificationCenter *center;

    center = [NSUserNotificationCenter defaultUserNotificationCenter];
    notification = [[NSUserNotification alloc] init];
    notification.title = title;
    notification.informativeText = detail;
    notification.soundName = NSUserNotificationDefaultSoundName;
    DEBUG_LOG("Sending NSNotification.\n");
    [center deliverNotification:notification];
}

/*
 * Implementation of the NSUserNotificationDelegate protocol.
 */

- (BOOL) userNotificationCenter: (NSUserNotificationCenter *) center
         shouldPresentNotification: (NSUserNotification *)notification
{
    (void) center;
    (void) notification;

    return YES;
}

- (void) userNotificationCenter:(NSUserNotificationCenter *)center
         didDeliverNotification:(NSUserNotification *)notification
{
    (void) center;
    (void) notification;
}

- (void) userNotificationCenter:(NSUserNotificationCenter *)center
	 didActivateNotification:(NSUserNotification *)notification
{
    (void) center;
    (void) notification;
}

@end
#pragma clang diagnostic pop

/*
 * Static variable which records whether the app is authorized to send
 * notifications via the UNUserNotificationCenter.
 */

#if BUILD_TARGET_HAS_UN_FRAMEWORK

@implementation TkUNNotifier : NSObject

- (void) requestAuthorization
{
    UNUserNotificationCenter *center;
    UNAuthorizationOptions options = UNAuthorizationOptionAlert |
				     UNAuthorizationOptionSound |
				     UNAuthorizationOptionBadge |
	    UNAuthorizationOptionProvidesAppNotificationSettings;
    if (![NSApp isSigned]) {

	/*
	 * No point in even asking.
	 */

	DEBUG_LOG("Unsigned app: UNUserNotifications are not available.\n");
	return;
    }

    center = [UNUserNotificationCenter currentNotificationCenter];
    [center requestAuthorizationWithOptions: options
	  completionHandler: ^(BOOL granted, NSError* error)
	    {
		if (error || granted == NO) {
		    DEBUG_LOG("Authorization for UNUserNotifications denied\n");
		}
	    }];
}

-  (void) postNotificationWithTitle: (NSString * ) title
			     message: (NSString * ) detail
{
    UNUserNotificationCenter *center;
    UNMutableNotificationContent* content;
    UNNotificationRequest *request;
    center = [UNUserNotificationCenter currentNotificationCenter];
    center.delegate = (id) self;
    content = [[UNMutableNotificationContent alloc] init];
    content.title = title;
    content.body = detail;
    content.sound = [UNNotificationSound defaultSound];
    content.categoryIdentifier = TkNotificationCategory;
    request = [UNNotificationRequest
		  requestWithIdentifier:[[NSUUID UUID] UUIDString]
				content:content
				trigger:nil
	       ];
    [center addNotificationRequest: request
	withCompletionHandler: ^(NSError* error) {
	    if (error) {
		DEBUG_LOG("addNotificationRequest: error = %s\n", \
			  [NSString stringWithFormat:@"%@", \
				    error.userInfo].UTF8String);
	    }
	}];
}

/*
 * Implementation of the UNUserNotificationDelegate protocol.
 */

- (void) userNotificationCenter:(UNUserNotificationCenter *)center
         didReceiveNotificationResponse:(UNNotificationResponse *)response
	 withCompletionHandler:(void (^)(void))completionHandler
{
    /*
     * Called when the user dismisses a notification.
     */

    DEBUG_LOG("didReceiveNotification\n");
    completionHandler();
}

- (void) userNotificationCenter:(UNUserNotificationCenter *)center
    willPresentNotification:(UNNotification *)notification
    withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{

    /*
     * This is called before presenting a notification, even when the user has
     * turned off notifications.
     */

    DEBUG_LOG("willPresentNotification\n");
    completionHandler(ALERT_OPTION);
}

- (void) userNotificationCenter:(UNUserNotificationCenter *)center
   openSettingsForNotification:(UNNotification *)notification
{
    DEBUG_LOG("openSettingsForNotification\n");
    // Does something need to be done here?
}

@end

#endif

/*
 *----------------------------------------------------------------------
 *
 * MacSystrayDestroy --
 *
 * 	Removes an intepreters icon from the status bar.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The icon is removed and memory is freed.
 *
 *----------------------------------------------------------------------
 */

static void
MacSystrayDestroy(
    ClientData clientData,
    TCL_UNUSED(Tcl_Interp *))
{
    StatusItemInfo info = (StatusItemInfo)clientData;
    if (info) {
	[*info release];
	ckfree(info);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * MacSystrayObjCmd --
 *
 * 	Main command for creating, displaying, and removing icons from the
 * 	status bar.
 *
 * Results:
 *
 *      A standard Tcl result.
 *
 * Side effects:
 *
 *	Management of icon display in the status bar.
 *
 *----------------------------------------------------------------------
 */

static int
MacSystrayObjCmd(
    void *clientData,
    Tcl_Interp * interp,
    int objc,
    Tcl_Obj *const *objv)
{
    Tk_Image tk_image;
    int result, idx;
    static const char *options[] =
	{"create", "modify", "destroy", NULL};
    typedef enum {TRAY_CREATE, TRAY_MODIFY, TRAY_DESTROY} optionsEnum;
    static const char *modifyOptions[] =
	{"image", "text", "b1_callback", "b3_callback", NULL};
    typedef enum {TRAY_IMAGE, TRAY_TEXT, TRAY_B1_CALLBACK, TRAY_B3_CALLBACK
        } modifyOptionsEnum;

    if ([NSApp macOSVersion] < 101000) {
	Tcl_AppendResult(interp,
	    "StatusItem icons not supported on macOS versions lower than 10.10",
	    NULL);
	return TCL_OK;
    }

    StatusItemInfo info = (StatusItemInfo)clientData;
    TkStatusItem *statusItem = *info;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "create | modify | destroy");
	return TCL_ERROR;
    }

    result = Tcl_GetIndexFromObjStruct(interp, objv[1], options,
				       sizeof(char *), "command", 0, &idx);

    if (result != TCL_OK) {
    	return TCL_ERROR;
    }
    switch((optionsEnum)idx) {
    case TRAY_CREATE: {

	if (objc < 3 ||  objc > 6) {
	    Tcl_WrongNumArgs(interp, 1, objv, "create -image -text -button1 -button3");
	    return TCL_ERROR;
	}

	if (statusItem == NULL) {
	    statusItem = [[TkStatusItem alloc] init: interp];
	    *info = statusItem;
	} else {
	    Tcl_AppendResult(interp, "Only one system tray icon supported per interpreter", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Create the icon.
	 */

	int width, height;
	Tk_Window tkwin = Tk_MainWindow(interp);
	TkWindow *winPtr = (TkWindow *)tkwin;
	Display *d = winPtr->display;
	NSImage *icon;

	tk_image = Tk_GetImage(interp, tkwin, Tcl_GetString(objv[2]), NULL, NULL);
	if (tk_image == NULL) {
	    return TCL_ERROR;
	}

	Tk_SizeOfImage(tk_image, &width, &height);
	if (width != 0 && height != 0) {
	    icon = TkMacOSXGetNSImageFromTkImage(d, tk_image,
						 width, height);
	    [statusItem setImagewithImage: icon];
	    Tk_FreeImage(tk_image);
	}

	/*
	 * Set the text for the tooltip.
	 */

	NSString *tooltip = [NSString stringWithUTF8String: Tcl_GetString(objv[3])];
	if (tooltip == nil) {
	    Tcl_AppendResult(interp, " unable to set tooltip for systray icon", NULL);
	    return TCL_ERROR;
	}

	[statusItem setTextwithString: tooltip];

	/*
	 * Set the proc for the callback.
	 */

	[statusItem setB1Callback : (objc > 4) ? objv[4] : NULL];
	[statusItem setB3Callback : (objc > 5) ? objv[5] : NULL];
	break;

    }
    case TRAY_MODIFY: {
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 1, objv, "modify object item");
	    return TCL_ERROR;
	}

	/*
	 * Modify the icon.
	 */

	result = Tcl_GetIndexFromObjStruct(interp, objv[2], modifyOptions,
					   sizeof(char *), "option", 0, &idx);

	if (result != TCL_OK) {
	    return TCL_ERROR;
	}
	switch ((modifyOptionsEnum)idx) {
	case TRAY_IMAGE: {
	    Tk_Window tkwin = Tk_MainWindow(interp);
	    TkWindow *winPtr = (TkWindow *)tkwin;
	    Display *d = winPtr -> display;
	    NSImage *icon;
	    int width, height;

	    tk_image = Tk_GetImage(interp, tkwin, Tcl_GetString(objv[3]), NULL, NULL);
	    if (tk_image == NULL) {
		Tcl_AppendResult(interp, " unable to obtain image for systray icon",
				 NULL);
		return TCL_ERROR;
	    }

	    Tk_SizeOfImage(tk_image, &width, &height);
	    if (width != 0 && height != 0) {
		icon = TkMacOSXGetNSImageFromTkImage(d, tk_image,
						     width, height);
		[statusItem setImagewithImage: icon];
	    }
	    Tk_FreeImage(tk_image);
	    break;
	}

        /*
         * Modify the text for the tooltip.
         */

	case TRAY_TEXT: {
	    NSString *tooltip = [NSString stringWithUTF8String:Tcl_GetString(objv[3])];
	    if (tooltip == nil) {
		Tcl_AppendResult(interp, "unable to set tooltip for systray icon",
				 NULL);
		return TCL_ERROR;
	    }

	    [statusItem setTextwithString: tooltip];
	    break;
	}

        /*
         * Modify the proc for the callback.
         */

	case TRAY_B1_CALLBACK: {
	    [statusItem setB1Callback : objv[3]];
	    break;
	}
	case TRAY_B3_CALLBACK: {
	    [statusItem setB3Callback : objv[3]];
	    break;
	}
    }
    break;
    }

    case TRAY_DESTROY: {
	/*
	 * Set all properties to nil, and release statusItem.
	 */
        [statusItem setImagewithImage: nil];
        [statusItem setTextwithString: nil];
        [statusItem setB1Callback : NULL];
        [statusItem setB3Callback : NULL];
        [statusItem release];
        *info = NULL;
        statusItem = NULL;
        break;
    }
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * SysNotifyObjCmd --
 *
 *      Create system notification.
 *
 * Results:
 *
 *      A standard Tcl result.
 *
 * Side effects:
 *
 *      System notifications are posted.
 *
 *-------------------------------z---------------------------------------
 */

static int SysNotifyObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp * interp,
    int objc,
    Tcl_Obj *const *objv)
{
    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "title message");
	return TCL_ERROR;
    }

    if ([NSApp macOSVersion] < 101000) {
	Tcl_AppendResult(interp,
	    "Notifications not supported on macOS versions lower than 10.10",
	     NULL);
	return TCL_OK;
    }

    NSString *title = [NSString stringWithUTF8String: Tcl_GetString(objv[1])];
    NSString *message = [NSString stringWithUTF8String: Tcl_GetString(objv[2])];

    /*
     * Update the authorization status in case the user enabled or disabled
     * notifications after the app started up.
     */

#if BUILD_TARGET_HAS_UN_FRAMEWORK

    if (UNnotifier && [NSApp isSigned]) {
    	UNUserNotificationCenter *center;

    	center = [UNUserNotificationCenter currentNotificationCenter];
        [center getNotificationSettingsWithCompletionHandler:
    	    ^(UNNotificationSettings *settings)
    	    {
#if !defined(DEBUG)
		(void) settings;
#endif
    		DEBUG_LOG("Reported authorization status is %ld\n",
			  settings.authorizationStatus);
    	    }];
           }

#endif

    if ([NSApp macOSVersion] < 101400 || ![NSApp isSigned]) {
	DEBUG_LOG("Using the NSUserNotificationCenter\n");
	[NSnotifier postNotificationWithTitle : title message: message];
    } else {

#if BUILD_TARGET_HAS_UN_FRAMEWORK

	DEBUG_LOG("Using the UNUserNotificationCenter\n");
	[UNnotifier postNotificationWithTitle : title message: message];
#endif
    }

    return TCL_OK;
}

#endif // if BUILD_TARGET_HAS_NOTIFICATION

/*
 *----------------------------------------------------------------------
 *
 * MacSystrayInit --
 *
 * 	Initialize this package and create script-level commands.
 *      This is called from TkpInit for each interpreter.
 *
 * Results:
 *
 *      A standard Tcl result.
 *
 * Side effects:
 *
 *	The tk systray and tk sysnotify commands are installed in an
 *	interpreter
 *
 *----------------------------------------------------------------------
 */

#if BUILD_TARGET_HAS_NOTIFICATION

int
MacSystrayInit(Tcl_Interp *interp)
{

    /*
     * Initialize the TkStatusItem for this interpreter and, if necessary,
     * the shared TkNSNotifier and TkUNNotifier.
     */

    StatusItemInfo info = (StatusItemInfo) ckalloc(sizeof(StatusItemInfo));
    *info = 0;

    if (NSnotifier == nil) {
	NSnotifier = [[TkNSNotifier alloc] init];
    }

#if BUILD_TARGET_HAS_UN_FRAMEWORK

    if (@available(macOS 10.14, *)) {
	UNUserNotificationCenter *center;
	UNNotificationCategory *category;
	NSSet *categories;

	if (UNnotifier == nil) {
	    UNnotifier = [[TkUNNotifier alloc] init];

	    /*
	     * Request authorization to use the UserNotification framework.  If
	     * the app code is signed and there are no notification preferences
	     * settings for this app, a dialog will be opened to prompt the
	     * user to choose settings.  Note that the request is asynchronous,
	     * so even if the preferences setting exists the result is not
	     * available immediately.
	     */

	    [UNnotifier requestAuthorization];
	}
	TkNotificationCategory = @"Basic Tk Notification";
	center = [UNUserNotificationCenter currentNotificationCenter];
	center = [UNUserNotificationCenter currentNotificationCenter];
	category = [UNNotificationCategory
		       categoryWithIdentifier:TkNotificationCategory
		       actions:@[]
		       intentIdentifiers:@[]
		       options: UNNotificationCategoryOptionNone];
	categories = [NSSet setWithObjects:category, nil];
	[center setNotificationCategories: categories];
    }
#endif

    Tcl_CreateObjCommand(interp, "::tk::systray::_systray", MacSystrayObjCmd, info,
            (Tcl_CmdDeleteProc *)MacSystrayDestroy);
    Tcl_CreateObjCommand(interp, "::tk::sysnotify::_sysnotify", SysNotifyObjCmd, NULL, NULL);
    return TCL_OK;
}

#else

int
MacSystrayInit(TCL_UNUSED(Tcl_Interp *))
{
    return TCL_OK;
}

#endif // BUILD_TARGET_HAS_NOTIFICATION

/*
 * 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
1
2
3
4
5
6



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

29
30

31
32
33
34
35
36
37
38
39
40






-
-
-
+
+
+







+
+










-
+

-
+
+
+







/*
 * 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 <[email protected]>
 * Copyright © 1996 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2005-2009 Daniel A. Steffen <[email protected]>
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXConstants.h"
#include "tkMacOSXWm.h"


/*
 * Forward declarations of procedures defined later in this file:
 */

#if MAC_OS_X_VERSION_MAX_ALLOWED < 1080
static int		DebuggerObjCmd (ClientData dummy, Tcl_Interp *interp,
					int objc, Tcl_Obj *const objv[]);
#endif
static int		PressButtonObjCmd (ClientData dummy, Tcl_Interp *interp,
					int objc, Tcl_Obj *const objv[]);
					int objc, Tcl_Obj *const *objv);
static int		InjectKeyEventObjCmd (ClientData dummy, Tcl_Interp *interp,
					int objc, Tcl_Obj *const objv[]);
					int objc, Tcl_Obj *const *objv);
static int		MenuBarHeightObjCmd (ClientData dummy, Tcl_Interp *interp,
					int objc, Tcl_Obj *const *objv);


/*
 *----------------------------------------------------------------------
 *
 * TkplatformtestInit --
 *
55
56
57
58
59
60
61
62

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

66
67
68
69
70
71
72
73







-
+







     */

#if MAC_OS_X_VERSION_MAX_ALLOWED < 1080
    Tcl_CreateObjCommand(interp, "debugger", DebuggerObjCmd, NULL, NULL);
#endif
    Tcl_CreateObjCommand(interp, "pressbutton", PressButtonObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "injectkeyevent", InjectKeyEventObjCmd, NULL, NULL);

    Tcl_CreateObjCommand(interp, "menubarheight", MenuBarHeightObjCmd, NULL, NULL);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * DebuggerObjCmd --
92
93
94
95
96
97
98

































99
100
101
102

103
104
105
106
107
108
109
110
111
112
113



114
115
116
117
118
119
120
121
122
123















124
125

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





138
139
140
141
142
143
144
145
146
147
148
149
150

151
152
153
154
155


156
157
158
159
160
161
162
163
164
165
166
167
168
169
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138

139






140
141



142
143
144
145
146
147
148
149
150
151



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167

168
169
170
171
172
173
174
175
176
177



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194

195
196
197
198
199

200
201
202
203
204
205
206
207

208
209
210
211
212
213
214







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



-
+
-
-
-
-
-
-


-
-
-
+
+
+







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

-
+









-
-
-
+
+
+
+
+












-
+




-
+
+






-







    return TCL_OK;
}
#endif

/*
 *----------------------------------------------------------------------
 *
 * MenuBarHeightObjCmd --
 *
 *	This procedure calls [NSMenu menuBarHeight] and returns the result
 *      as an integer.  Windows can never be placed to overlap the MenuBar,
 *      so tests need to be aware of its size.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
MenuBarHeightObjCmd(
    TCL_UNUSED(void *),		/* Not used. */
    Tcl_Interp *interp,			/* Not used. */
    TCL_UNUSED(int),				/* Not used. */
    TCL_UNUSED(Tcl_Obj *const *))		/* Not used. */
{
    static int height = 0;
    if (height == 0) {
	height = (int) [[NSApp mainMenu] menuBarHeight];
    }
    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(height));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTestLogDisplay --
 *
 *      The test image display procedure calls this to determine whether it
 *      should write a log message recording that it has being run.  On OSX
 *      should write a log message recording that it has being run.
 *      10.14 and later, only calls to the display procedure which occur inside
 *      of the drawRect method should be logged, since those are the only ones
 *      which actually draw anything.  On earlier systems the opposite is true.
 *      The calls from within the drawRect method are redundant, since the
 *      first time the display procedure is run it will do the drawing and that
 *      first call will usually not occur inside of drawRect.
 *
 * Results:
 *      On OSX 10.14 and later, returns true if and only if called from
 *      within [NSView drawRect].  On earlier systems returns false if
 *      and only if called from with [NSView drawRect].
 *      Returns true if and only if the NSView of the drawable is the
 *      current focusView, which on 10.14 and newer systems can only be the
 *      case when within [NSView drawRect].
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */
MODULE_SCOPE Bool
TkTestLogDisplay(void) {
    if ([NSApp macOSVersion] >= 101400) {
	return [NSApp isDrawing];
TkTestLogDisplay(
    Drawable drawable)
{
    MacDrawable *macWin = (MacDrawable *)drawable;
    NSWindow *win = nil;
    if (macWin->toplevel && macWin->toplevel->winPtr &&
	macWin->toplevel->winPtr->wmInfoPtr &&
	macWin->toplevel->winPtr->wmInfoPtr->window) {
	win = macWin->toplevel->winPtr->wmInfoPtr->window;
    } else if (macWin->winPtr && macWin->winPtr->wmInfoPtr &&
	       macWin->winPtr->wmInfoPtr->window) {
	win = macWin->winPtr->wmInfoPtr->window;
    }
    if (win) {
	return ([win contentView] == [NSView focusView]);
    } else {
	return ![NSApp isDrawing];
	return True;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * PressButtonObjCmd --
 *
 *	This Tcl command simulates a button press at a specific screen
 *      location.  It injects NSEvents into the NSApplication event queue,
 *      as opposed to adding events to the Tcl queue as event generate
 *      would do.  One application is for testing the grab command.
 *      location.  It injects NSEvents into the NSApplication event queue, as
 *      opposed to adding events to the Tcl queue as event generate would do.
 *      One application is for testing the grab command. These events have
 *      their unused context property set to 1 as a signal indicating that they
 *      should not be ignored by [NSApp tkProcessMouseEvent].
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
PressButtonObjCmd(
    ClientData dummy,
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    int x = 0, y = 0, i, value, wNum;
    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};
    (void)dummy;

    if (screens && [screens count]) {
	ScreenHeight = [[screens objectAtIndex:0] frame].size.height;
    }

    if (objc != 3) {
        Tcl_WrongNumArgs(interp, 1, objv, "x y");
183
184
185
186
187
188
189
190






191
192
193
194
195
196

197
198

199
200
201
202
203
204
205
206

207
208

209
210
211
212
213
214
215
216

217
218

219
220

221
222
223
224
225
226
227

228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
228
229
230
231
232
233
234

235
236
237
238
239
240
241
242
243
244
245

246
247

248
249
250
251
252
253
254
255

256
257

258
259
260
261
262
263
264
265

266
267

268
269

270
271
272
273
274
275
276

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

294
295
296
297
298
299
300







-
+
+
+
+
+
+





-
+

-
+







-
+

-
+







-
+

-
+

-
+






-
+
















-







	default:
	    break;
	}
    }
    pt.x = loc.x = x;
    pt.y = y;
    loc.y = ScreenHeight - y;
    wNum = 0;

    /*
     *  We set the window number and the eventNumber to -1 as a signal to
     *  processMouseEvent.
     */

    CGWarpMouseCursorPosition(pt);
    motion = [NSEvent mouseEventWithType:NSMouseMoved
	location:loc
	modifierFlags:0
	timestamp:GetCurrentEventTime()
	windowNumber:wNum
	windowNumber:signal
	context:nil
	eventNumber:0
	eventNumber:signal
	clickCount:1
	pressure:0.0];
    [NSApp postEvent:motion atStart:NO];
    press = [NSEvent mouseEventWithType:NSLeftMouseDown
	location:loc
	modifierFlags:0
	timestamp:GetCurrentEventTime()
	windowNumber:wNum
	windowNumber:signal
	context:nil
	eventNumber:1
	eventNumber:signal
	clickCount:1
	pressure:0.0];
    [NSApp postEvent:press atStart:NO];
    release = [NSEvent mouseEventWithType:NSLeftMouseUp
	location:loc
	modifierFlags:0
	timestamp:GetCurrentEventTime()
	windowNumber:wNum
	windowNumber:signal
	context:nil
	eventNumber:2
	eventNumber:signal
	clickCount:1
	pressure:0.0];
	pressure:-1.0];
    [NSApp postEvent:release atStart:NO];
    return TCL_OK;
}

static int
InjectKeyEventObjCmd(
    ClientData dummy,
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    static const char *const optionStrings[] = {
	"press", "release", "flagschanged", NULL};
    NSUInteger types[3] = {NSKeyDown, NSKeyUp, NSFlagsChanged};
    static const char *const argStrings[] = {
	"-shift", "-control", "-option", "-command", "-function", "-x", "-y", NULL};
    enum args {KEYEVENT_SHIFT, KEYEVENT_CONTROL, KEYEVENT_OPTION, KEYEVENT_COMMAND,
	       KEYEVENT_FUNCTION, KEYEVENT_X, KEYEVENT_Y};
    int i, index, keysym, mods = 0, x = 0, y = 0;
    NSString *chars = nil, *unmod = nil, *upper, *lower;
    NSEvent *keyEvent;
    NSUInteger type;
    MacKeycode macKC;
    (void)dummy;

    if (objc < 3) {
    wrongArgs:
        Tcl_WrongNumArgs(interp, 1, objv, "option keysym ?arg?");
        return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,

Changes to macosx/tkMacOSXWindowEvent.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






-
-
-
-
+
+
+
+







/*
 * 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 <[email protected]>
 * Copyright (c) 2015 Kevin Walzer/WordTech Communications LLC.
 * Copyright (c) 2015 Marc Culler.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2005-2009 Daniel A. Steffen <[email protected]>
 * 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"
26
27
28
29
30
31
32
33
34


35
36
37
38
39
40
41

42
43


44
45
46
47
48
49
50
26
27
28
29
30
31
32


33
34
35
36

37
38
39

40
41

42
43
44
45
46
47
48
49
50







-
-
+
+


-



-
+

-
+
+







#endif
*/

/*
 * Declaration of functions used only in this file
 */

static int		GenerateUpdates(HIShapeRef updateRgn,
			   CGRect *updateBounds, TkWindow *winPtr);
static int		GenerateUpdates(
			    CGRect *updateBounds, TkWindow *winPtr);
static int		GenerateActivateEvents(TkWindow *winPtr,
			    int activeFlag);
static void		DoWindowActivate(ClientData clientData);

#pragma mark TKApplication(TKWindowEvent)

#ifdef TK_MAC_DEBUG_NOTIFICATIONS
extern NSString *NSWindowDidOrderOnScreenNotification;
extern NSString *NSWindowWillOrderOnScreenNotification;
extern NSString *NSWindowDidOrderOnScreenNotification;

#ifdef TK_MAC_DEBUG_NOTIFICATIONS
extern NSString *NSWindowDidOrderOffScreenNotification;
#endif


@implementation TKApplication(TKWindowEvent)

- (void) windowActivation: (NSNotification *) notification
86
87
88
89
90
91
92
93
94
95
96



97
98

99
100
101

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

118
119
120
121
122



123
124
125


126
127
128
129
130




131
132

133
134
135
136
137
138
139
140
141
142
86
87
88
89
90
91
92




93
94
95
96

97



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

114

115



116
117
118
119


120
121
122




123
124
125
126
127

128



129
130
131
132
133
134
135







-
-
-
-
+
+
+

-
+
-
-
-
+















-
+
-

-
-
-
+
+
+

-
-
+
+

-
-
-
-
+
+
+
+

-
+
-
-
-







	}
	if (!movedOnly && (winPtr->changes.width != bounds.size.width ||
		winPtr->changes.height !=  bounds.size.height)) {
	    width = bounds.size.width - wmPtr->xInParent;
	    height = bounds.size.height - wmPtr->yInParent;
	    flags |= TK_SIZE_CHANGED;
	}
	if (Tcl_GetServiceMode() != TCL_SERVICE_NONE) {
	    /*
	     * Propagate geometry changes immediately.
	     */
	/*
	 * Propagate geometry changes immediately.
	 */

	    flags |= TK_MACOSX_HANDLE_EVENT_IMMEDIATELY;
	flags |= TK_MACOSX_HANDLE_EVENT_IMMEDIATELY;
	}

	TkGenWMConfigureEvent((Tk_Window) winPtr, x, y, width, height, flags);
	TkGenWMConfigureEvent((Tk_Window)winPtr, x, y, width, height, flags);
    }

}

- (void) windowExpanded: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	winPtr->wmInfoPtr->hints.initial_state =
		TkMacOSXIsWindowZoomed(winPtr) ? ZoomState : NormalState;
	Tk_MapWindow((Tk_Window) winPtr);
	Tk_MapWindow((Tk_Window)winPtr);
	if (Tcl_GetServiceMode() != TCL_SERVICE_NONE) {

	    /*
	     * Process all Tk events generated by Tk_MapWindow().
	     */
	/*
	 * Process all Tk events generated by Tk_MapWindow().
	 */

	    while (Tcl_ServiceEvent(0)) {}
	    while (Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_DONT_WAIT)) {}
	while (Tcl_ServiceEvent(0)) {}
	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {}

	    /*
	     * NSWindowDidDeminiaturizeNotification is received after
	     * NSWindowDidBecomeKeyNotification, so activate manually
	     */
	/*
	 * NSWindowDidDeminiaturizeNotification is received after
	 * NSWindowDidBecomeKeyNotification, so activate manually
	 */

	    GenerateActivateEvents(winPtr, 1);
	GenerateActivateEvents(winPtr, 1);
	} else {
	    Tcl_DoWhenIdle(DoWindowActivate, winPtr);
	}
    }
}

- (NSRect)windowWillUseStandardFrame:(NSWindow *)window
                        defaultFrame:(NSRect)newFrame
{
    (void)window;
150
151
152
153
154
155
156

157
158
159
160
161
162
163
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157







+







    return newFrame;
}

- (NSSize)window:(NSWindow *)window
  willUseFullScreenContentSize:(NSSize)proposedSize
{
    (void)window;

    /*
     * We don't need to change the proposed size, but we do need to implement
     * this method.  Otherwise the full screen window will be sized to the
     * screen's visibleFrame, leaving black bands at the top and bottom.
     */

    return proposedSize;
184
185
186
187
188
189
190
191

192
193
194
195
196
197
198
199
200
201
202
203

204
205
206
207
208
209
210
211
212




























213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250

251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268


269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
178
179
180
181
182
183
184

185
186
187
188
189
190
191
192
193
194
195
196

197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
















249
250
251
252
253
254
255

256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286


287
288
289
290
291
292
293







-
+











-
+









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














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







-
+


















+
+










-
-







#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	Tk_UnmapWindow((Tk_Window) winPtr);
	Tk_UnmapWindow((Tk_Window)winPtr);
    }
}

- (BOOL) windowShouldClose: (NSWindow *) w
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, w);
#endif
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	TkGenWMDestroyEvent((Tk_Window) winPtr);
	TkGenWMDestroyEvent((Tk_Window)winPtr);
    }

    /*
     * If necessary, TkGenWMDestroyEvent() handles [close]ing the window, so
     * can always return NO from -windowShouldClose: for a Tk window.
     */

    return (winPtr ? NO : YES);
}

- (void) windowBecameVisible: (NSNotification *) notification
{
    NSWindow *window = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(window);
    if (winPtr) {
	TKContentView *view = [window contentView];

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101500
	if (@available(macOS 10.15, *)) {
	    [view viewDidChangeEffectiveAppearance];
	}
#endif
	[view addTkDirtyRect:[view bounds]];
	Tcl_CancelIdleCall(TkMacOSXDrawAllViews, NULL);
	Tcl_DoWhenIdle(TkMacOSXDrawAllViews, NULL);
    }
}

- (void) windowMapped: (NSNotification *) notification
{
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {}
    }
}

#ifdef TK_MAC_DEBUG_NOTIFICATIONS

- (void) windowDragStart: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
}

- (void) windowLiveResize: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    //BOOL start = [[notification name] isEqualToString:NSWindowWillStartLiveResizeNotification];
}

- (void) windowMapped: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	//Tk_MapWindow((Tk_Window) winPtr);
    }
}

- (void) windowBecameVisible: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
}

- (void) windowUnmapped: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	//Tk_UnmapWindow((Tk_Window) winPtr);
	//Tk_UnmapWindow((Tk_Window)winPtr);
    }
}

#endif /* TK_MAC_DEBUG_NOTIFICATIONS */

- (void) _setupWindowNotifications
{
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

#define observe(n, s) \
	[nc addObserver:self selector:@selector(s) name:(n) object:nil]

    observe(NSWindowDidBecomeKeyNotification, windowActivation:);
    observe(NSWindowDidResignKeyNotification, windowActivation:);
    observe(NSWindowDidMoveNotification, windowBoundsChanged:);
    observe(NSWindowDidResizeNotification, windowBoundsChanged:);
    observe(NSWindowDidDeminiaturizeNotification, windowExpanded:);
    observe(NSWindowDidMiniaturizeNotification, windowCollapsed:);
    observe(NSWindowWillOrderOnScreenNotification, windowMapped:);
    observe(NSWindowDidOrderOnScreenNotification, windowBecameVisible:);

#if !(MAC_OS_X_VERSION_MAX_ALLOWED < 1070)
    observe(NSWindowDidEnterFullScreenNotification, windowEnteredFullScreen:);
    observe(NSWindowDidExitFullScreenNotification, windowExitedFullScreen:);
#endif

#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    observe(NSWindowWillMoveNotification, windowDragStart:);
    observe(NSWindowWillStartLiveResizeNotification, windowLiveResize:);
    observe(NSWindowDidEndLiveResizeNotification, windowLiveResize:);
    observe(NSWindowWillOrderOnScreenNotification, windowMapped:);
    observe(NSWindowDidOrderOnScreenNotification, windowBecameVisible:);
    observe(NSWindowDidOrderOffScreenNotification, windowUnmapped:);
#endif
#undef observe

}
@end

407
408
409
410
411
412
413
414
415


416
417
418
419
420
421
422
423

424
425
426

427
428














429
430

431

432
433
434
435
436
437
438
439

440
441

442
443
444
445
446
447
448

449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470

471
472
473

474
475
476
477
478
479
480
481
482
483
484

485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501

502
503
504
505
506
507
508
509
510
511
512
513
514

515
516
517
518
519
520
521
522
523
524

525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599

600
601
602
603
604

605
606
607
608
609
610
611
413
414
415
416
417
418
419


420
421
422
423
424
425
426
427


428

429
430
431


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

447
448
449
450
451
452
453
454
455
456

457
458

459
460
461
462
463
464
465

466
467
468
469
470
471
472

473
474
475
476
477
478

479
480
481
482
483



484

485

486
487
488









489



490
491
492
493
494
495
496
497
498
499
500
501
502

503
504
505
506
507
508
509
510
511
512
513
514
515

516
517
518
519
520
521
522
523
524
525

526
527
528
529
530
531
532
533
534
535




















































536
537
538
539
540
541
542
543
544
545
546
547
548

549
550
551
552
553

554
555
556
557
558
559
560
561







-
-
+
+






-
-
+
-


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

-
+

+







-
+

-
+






-
+






-






-





-
-
-
+
-

-
+


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













-
+












-
+









-
+









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













-
+




-
+







 *      procedures will be run in a predictable sequence as Tcl idle tasks.
 *
 * Results:
 *      True if called from the drawRect method of a TKContentView with
 *      tkwin NULL or pointing to a widget in the current focusView.
 *
 * Side effects:
 *	The tkwin parameter may be recorded to handle redrawing the widget
 *      later.
 *	Currently none.  One day the tkwin parameter may be recorded to
 *      handle redrawing the widget later.
 *
 *----------------------------------------------------------------------
 */

int
TkpWillDrawWidget(Tk_Window tkwin) {
    if (![NSApp isDrawing]) {
	return 0;
    int result;
    }
    if (tkwin) {
	TkWindow *winPtr = (TkWindow *)tkwin;
	TKContentView *view = (TKContentView *)TkMacOSXGetNSViewForDrawable(
	NSView *view = TkMacOSXDrawableView(winPtr->privatePtr);
	return (view == [NSView focusView]);
	    (Drawable)winPtr->privatePtr);
	result = ([NSApp isDrawing] && view == [NSView focusView]);
#if 0
	printf("TkpWillDrawWidget: %s %d  %d \n", Tk_PathName(tkwin),
	       [NSApp isDrawing], (view == [NSView focusView]));
	if (!result) {
	    NSRect dirtyRect;
	    TkMacOSXWinNSBounds(winPtr, view, &dirtyRect);
	    printf("TkpAppCanDraw: dirtyRect for %s is %s\n",
		   Tk_PathName(tkwin),
		   NSStringFromRect(dirtyRect).UTF8String);
	    [view addTkDirtyRect:dirtyRect];
	}
#endif
    } else {
	return 1;
	result = [NSApp isDrawing];
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * GenerateUpdates --
 *
 *	Given a Macintosh update region and a Tk window this function geneates
 *	Given an update rectangle and a Tk window, this function generates
 *	an X Expose event for the window if it meets the update region. The
 *	function will then recursivly have each damaged window generate Expose
 *	function will then recursively have each damaged window generate Expose
 *	events for its child windows.
 *
 * Results:
 *	True if event(s) are generated - false otherwise.
 *
 * Side effects:
 *	Additional events may be place on the Tk event queue.
 *	Additional events may be placed on the Tk event queue.
 *
 *----------------------------------------------------------------------
 */

static int
GenerateUpdates(
    HIShapeRef updateRgn,
    CGRect *updateBounds,
    TkWindow *winPtr)
{
    TkWindow *childPtr;
    XEvent event;
    CGRect bounds, damageBounds;
    HIShapeRef boundsRgn, damageRgn;

    TkMacOSXWinCGBounds(winPtr, &bounds);
    if (!CGRectIntersectsRect(bounds, *updateBounds)) {
	return 0;
    }
    if (!HIShapeIntersectsRect(updateRgn, &bounds)) {
	return 0;
    }


    /*
     * Compute the bounding box of the area that the damage occured in.
     * Compute the bounding box of the area that the damage occurred in.
     */

    boundsRgn = HIShapeCreateWithRect(&bounds);
    damageRgn = HIShapeCreateIntersection(updateRgn, boundsRgn);
    if (HIShapeIsEmpty(damageRgn)) {
	CFRelease(damageRgn);
	CFRelease(boundsRgn);
	return 0;
    }
    HIShapeGetBounds(damageRgn, &damageBounds);

    damageBounds = CGRectIntersection(bounds, *updateBounds);
    CFRelease(damageRgn);
    CFRelease(boundsRgn);

    event.xany.serial = LastKnownRequestProcessed(Tk_Display(winPtr));
    event.xany.send_event = false;
    event.xany.window = Tk_WindowId(winPtr);
    event.xany.display = Tk_Display(winPtr);
    event.type = Expose;
    event.xexpose.x = damageBounds.origin.x - bounds.origin.x;
    event.xexpose.y = damageBounds.origin.y - bounds.origin.y;
    event.xexpose.width = damageBounds.size.width;
    event.xexpose.height = damageBounds.size.height;
    event.xexpose.count = 0;
    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);

#ifdef TK_MAC_DEBUG_DRAWING
    TKLog(@"Expose %p {{%d, %d}, {%d, %d}}", event.xany.window, event.xexpose.x,
    TKLog(@"Exposed %p {{%d, %d}, {%d, %d}}", event.xany.window, event.xexpose.x,
	event.xexpose.y, event.xexpose.width, event.xexpose.height);
#endif

    /*
     * Generate updates for the children of this window
     */

    for (childPtr = winPtr->childList; childPtr != NULL;
	    childPtr = childPtr->nextPtr) {
	if (!Tk_IsMapped(childPtr) || Tk_IsTopLevel(childPtr)) {
	    continue;
	}
	GenerateUpdates(updateRgn, updateBounds, childPtr);
	GenerateUpdates(updateBounds, childPtr);
    }

    /*
     * Generate updates for any contained windows
     */

    if (Tk_IsContainer(winPtr)) {
	childPtr = TkpGetOtherWindow(winPtr);
	if (childPtr != NULL && Tk_IsMapped(childPtr)) {
	    GenerateUpdates(updateRgn, updateBounds, childPtr);
	    GenerateUpdates(updateBounds, childPtr);
	}

	/*
	 * TODO: Here we should handle out of process embedding.
	 */
    }

    return 1;
}

/*
 *----------------------------------------------------------------------
 *
 * GenerateActivateEvents --
 *
 *	Given a Macintosh window activate event this function generates all the
 *	X Activate events needed by Tk.
 *
 * Results:
 *	True if event(s) are generated - false otherwise.
 *
 * Side effects:
 *	Additional events may be place on the Tk event queue.
 *
 *----------------------------------------------------------------------
 */

int
GenerateActivateEvents(
    TkWindow *winPtr,
    int activeFlag)
{
    TkGenerateActivateEvents(winPtr, activeFlag);
    if (activeFlag || ![NSApp isActive]) {
	TkMacOSXGenerateFocusEvent(winPtr, activeFlag);
    }
    return true;
}

/*
 *----------------------------------------------------------------------
 *
 * DoWindowActivate --
 *
 *	Idle handler that calls GenerateActivateEvents().
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Additional events may be place on the Tk event queue.
 *
 *----------------------------------------------------------------------
 */

void
DoWindowActivate(
    ClientData clientData)
{
    GenerateActivateEvents(clientData, 1);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGenerateFocusEvent --
 *
 *	Given a Macintosh window activate event this function generates all
 *	the X Focus events needed by Tk.
 *
 * Results:
 *	True if event(s) are generated - false otherwise.
 *
 * Side effects:
 *	Additional events may be place on the Tk event queue.
 *	Additional events may be placed on the Tk event queue.
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE int
static int
TkMacOSXGenerateFocusEvent(
    TkWindow *winPtr,		/* Root X window for event. */
    int activeFlag)
{
    XEvent event;

    /*
636
637
638
639
640
641
642





























643
644
645
646
647
648
649
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628







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







    event.xfocus.mode = NotifyNormal;
    event.xfocus.detail = NotifyDetailNone;

    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
    return true;
}

/*
 *----------------------------------------------------------------------
 *
 * GenerateActivateEvents --
 *
 *	Given a Macintosh window activate event this function generates all the
 *	X Activate events needed by Tk.
 *
 * Results:
 *	True if event(s) are generated - false otherwise.
 *
 * Side effects:
 *	Additional events may be placed on the Tk event queue.
 *
 *----------------------------------------------------------------------
 */

int
GenerateActivateEvents(
    TkWindow *winPtr,
    int activeFlag)
{
    TkGenerateActivateEvents(winPtr, activeFlag);
    if (activeFlag || ![NSApp isActive]) {
	TkMacOSXGenerateFocusEvent(winPtr, activeFlag);
    }
    return true;
}

/*
 *----------------------------------------------------------------------
 *
 * TkGenWMConfigureEvent --
 *
 *	Generate a ConfigureNotify event for Tk. Depending on the value of flag
 *	the values of width/height, x/y, or both may be changed.
750
751
752
753
754
755
756
757

758
759
760
761
762
763
764
729
730
731
732
733
734
735

736
737
738
739
740
741
742
743







-
+







	    wmPtr->configWidth = width;
	    wmPtr->configHeight = height;
	}
    }

    /*
     * Now set up the changes structure. Under X we wait for the
     * ConfigureNotify to set these values. On the Mac we know imediatly that
     * ConfigureNotify to set these values. On the Mac we know immediately that
     * this is what we want - so we just set them. However, we need to make
     * sure the windows clipping region is marked invalid so the change is
     * visible to the subwindow.
     */

    winPtr->changes.x = x;
    winPtr->changes.y = y;
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
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







-
+













-
-
+
+







	    Tcl_Preserve(protPtr);
	    interp = protPtr->interp;
	    Tcl_Preserve(interp);
	    result = Tcl_EvalEx(interp, protPtr->command, -1, TCL_EVAL_GLOBAL);
	    if (result != TCL_OK) {
		Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
			"\n    (command for \"%s\" window manager protocol)",
			Tk_GetAtomName((Tk_Window) winPtr, protocol)));
			Tk_GetAtomName((Tk_Window)winPtr, protocol)));
		Tcl_BackgroundException(interp, result);
	    }
	    Tcl_Release(interp);
	    Tcl_Release(protPtr);
	    return;
	}
    }

    /*
     * No handler was present for this protocol. If this is a WM_DELETE_WINDOW
     * message then just destroy the window.
     */

    if (protocol == Tk_InternAtom((Tk_Window) winPtr, "WM_DELETE_WINDOW")) {
	Tk_DestroyWindow((Tk_Window) winPtr);
    if (protocol == Tk_InternAtom((Tk_Window)winPtr, "WM_DELETE_WINDOW")) {
	Tk_DestroyWindow((Tk_Window)winPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MacOSXIsAppInFront --
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
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







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



-
-




+
-
-
+
+
+















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











-
+







ConfigureRestrictProc(
    TCL_UNUSED(void *),
    XEvent *eventPtr)
{
    return (eventPtr->type==ConfigureNotify ? TK_PROCESS_EVENT : TK_DEFER_EVENT);
}

/*
 * If a window gets mapped inside the drawRect method, this will be run as an
 * idle task, after drawRect returns, to clean up the mess.
 */

@implementation TKContentView(TKWindowEvent)
static void
RedisplayView(
    ClientData clientdata)
{

    NSView *view = (NSView *) clientdata;

- (void) addTkDirtyRect: (NSRect) rect
    /*
     * Make sure that we are not trying to displaying a view that no longer
     * exists. Must call [NSApp windows] because [NSApp orderedWindows] excludes
     * floating/utility windows and other window panels.
     */

{
    for (NSWindow *w in [NSApp windows]) {
	if ([w contentView] == view) {
	    [view setNeedsDisplay:YES];
    _tkNeedsDisplay = YES;
	    break;
	}
    }
    _tkDirtyRect = NSUnionRect(_tkDirtyRect, rect);
    [NSApp setNeedsToDraw:YES];
}

}

- (void) clearTkDirtyRect
{
@implementation TKContentView(TKWindowEvent)
    _tkNeedsDisplay = NO;
    _tkDirtyRect = NSZeroRect;
    [NSApp setNeedsToDraw:NO];
}

- (void) drawRect: (NSRect) rect
{
    const NSRect *rectsBeingDrawn;
    NSInteger rectsBeingDrawnCount;
    (void)rect;

#ifdef TK_MAC_DEBUG_DRAWING
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
    if (winPtr) {
    if (winPtr) fprintf(stderr, "drawRect: drawing %s\n",
			Tk_PathName(winPtr));
	fprintf(stderr, "drawRect: drawing %s in %s\n",
	    Tk_PathName(winPtr), NSStringFromRect(rect).UTF8String);
    }
#endif

    /*
     * We do not allow recursive calls to drawRect, but we only log them on OSX
     * > 10.13, where they should never happen.
     */

    if ([NSApp isDrawing]) {
	if ([NSApp macOSVersion] > 101300) {
	    TKLog(@"WARNING: a recursive call to drawRect was aborted.");
	}
	return;
    }

    [NSApp setIsDrawing: YES];

    [self clearTkDirtyRect];
    [self getRectsBeingDrawn:&rectsBeingDrawn count:&rectsBeingDrawnCount];
    CGFloat height = [self bounds].size.height;
    HIMutableShapeRef drawShape = HIShapeCreateMutable();

    while (rectsBeingDrawnCount--) {
	CGRect r = NSRectToCGRect(*rectsBeingDrawn++);

#ifdef TK_MAC_DEBUG_DRAWING
	fprintf(stderr, "drawRect: %dx%d@(%d,%d)\n", (int)r.size.width,
	       (int)r.size.height, (int)r.origin.x, (int)r.origin.y);
#endif

	r.origin.y = height - (r.origin.y + r.size.height);
	HIShapeUnionWithRect(drawShape, &r);
    }
    [self generateExposeEvents:(HIShapeRef)drawShape];
    [self generateExposeEvents:rect];
    CFRelease(drawShape);
    [NSApp setIsDrawing: NO];
    [NSApp setIsDrawing:NO];

    if ([self needsRedisplay]) {
	[self setNeedsRedisplay:NO];
	Tcl_DoWhenIdle(RedisplayView, self);
    }

#ifdef TK_MAC_DEBUG_DRAWING
    fprintf(stderr, "drawRect: done.\n");
#endif
}

-(void) setFrameSize: (NSSize)newsize
{
    [super setFrameSize: newsize];
    NSWindow *w = [self window];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);
    Tk_Window tkwin = (Tk_Window) winPtr;
    Tk_Window tkwin = (Tk_Window)winPtr;

    if (![self inLiveResize] &&
	[w respondsToSelector: @selector (tkLayoutChanged)]) {
	[(TKWindow *)w tkLayoutChanged];
    }

    if (winPtr) {
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
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







-
+
+
+


-
-
-
+
+
-
+
















-
+


-

+








-
+
+


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


+
+

-
+
+



-
+











-
-
+
+

+





-
-
-
+
+
+
+
+
+
+


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


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


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














-
+







	 */

	TkMacOSXSetDrawingEnabled(winPtr, 1);
	TkMacOSXInvalClipRgns(tkwin);
	TkMacOSXUpdateClipRgn(winPtr);

	 /*
	  * Generate and process expose events to redraw the window.
	  * Generate and process expose events to redraw the window.  To avoid
	  * crashes, only do this if we are being called from drawRect.  See
	  * ticket [1fa8c3ed8d].
	  */

	HIRect bounds = NSRectToCGRect([self bounds]);
	HIShapeRef shape = HIShapeCreateWithRect(&bounds);
	[self generateExposeEvents: shape];
	if([NSApp isDrawing] || [self inLiveResize]) {
	    [self generateExposeEvents: [self bounds]];
	[w displayIfNeeded];
	}

	/*
	 * Finally, unlock the main autoreleasePool.
	 */

	[NSApp _unlockAutoreleasePool];
    }
}

/*
 * Core method of this class: generates expose events for redrawing.  The
 * expose events are immediately removed from the Tcl event loop and processed.
 * This causes drawing procedures to be scheduled as idle events.  Then all
 * pending idle events are processed so the drawing will actually take place.
 */

- (void) generateExposeEvents: (HIShapeRef) shape
- (void) generateExposeEvents: (NSRect) rect
{
    unsigned long serial;
    CGRect updateBounds;
    int updatesNeeded;
    CGRect updateBounds;
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
    ClientData oldArg;
    Tk_RestrictProc *oldProc;
    if (!winPtr) {
	return;
    }

    /*
     * Generate Tk Expose events.
     * Generate Tk Expose events.  All of these events will share the same
     * serial number.
     */

    HIShapeGetBounds(shape, &updateBounds);

    updateBounds = NSRectToCGRect(rect);
    updateBounds.origin.y = ([self bounds].size.height - updateBounds.origin.y
    /*
     * All of these events will share the same serial number.
     */

			     - updateBounds.size.height);
    serial = LastKnownRequestProcessed(Tk_Display(winPtr));
    updatesNeeded = GenerateUpdates(shape, &updateBounds, winPtr);
    updatesNeeded = GenerateUpdates(&updateBounds, winPtr);

    if (updatesNeeded) {

	serial = LastKnownRequestProcessed(Tk_Display(winPtr));

	/*
	 * First process all of the Expose events.
	 * Use the ExposeRestrictProc to process only the expose events.  This
	 * will create idle drawing tasks, which we handle before we return.
	 */

    	oldProc = Tk_RestrictEvents(ExposeRestrictProc, UINT2PTR(serial), &oldArg);
    	while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {};
    	while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS|TCL_DONT_WAIT)) {};
    	Tk_RestrictEvents(oldProc, oldArg, &oldArg);

	/*
	 * Starting with OSX 10.14, which uses Core Animation to draw windows,
	 * all drawing must be done within the drawRect method.  (The CGContext
	 * which draws to the backing CALayer is created by the NSView before
	 * calling drawRect, and destroyed when drawRect returns.  Drawing done
	 * with the current CGContext outside of the drawRect method has no
	 * effect.)
	 *
	 * Fortunately, Tk schedules all drawing to be done while Tcl is idle.
	 * So we can do the drawing by processing all of the idle events that
	 * were created when the expose events were processed.
	 * So to run any display procs which were scheduled by the expose
	 * events we process all idle events before returning.
	 */

	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {}
    }
}

/*
 * This method is called when a user changes between light and dark mode. The
 * implementation here generates a Tk virtual event which can be bound to a
 * function that redraws the window in an appropriate style.
 * In macOS 10.14 and later this method is called when a user changes between
 * light and dark mode or changes the accent color. The implementation
 * generates two virtual events.  The first is either <<LightAqua>> or
 * <<DarkAqua>>, depending on the view's current effective appearance.  The
 * second is <<AppearnceChanged>> and has a data string describing the
 * effective appearance of the view and the current accent and highlight
 * colors.
 */

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400

static const char *const accentNames[] = {
    "Graphite",
    "Red",
    "Orange",
    "Yellow",
    "Green",
    "Blue",
    "Purple",
    "Pink"
};

- (void) viewDidChangeEffectiveAppearance
{
    XVirtualEvent event;
    int x, y;
    NSWindow *w = [self window];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);
    Tk_Window tkwin = (Tk_Window) winPtr;

    if (!winPtr) {
    Tk_Window tkwin = (Tk_Window)TkMacOSXGetTkWindow([self window]);
    if (!tkwin) {
	return;
    }
    NSAppearanceName effectiveAppearanceName = [[self effectiveAppearance] name];
    NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
    static const char *defaultColor = NULL;

    if (effectiveAppearanceName == NSAppearanceNameAqua) {
	Tk_SendVirtualEvent(tkwin, "LightAqua", NULL);
    } else if (effectiveAppearanceName == NSAppearanceNameDarkAqua) {
	Tk_SendVirtualEvent(tkwin, "DarkAqua", NULL);
    }
    if ([NSApp macOSVersion] < 101500) {

	/*
	 * Mojave cannot handle the KVO shenanigans that we need for the
	 * highlight and accent color notifications.
	 */

	return;
    }
    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);
    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"];
    event.root = XRootWindow(Tk_Display(tkwin), 0);
    event.subwindow = None;
    event.time = TkpGetMS();
    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;
    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;
    if (TkMacOSXInDarkMode(tkwin)) {
    char data[256];
    snprintf(data, 256, "Appearance %s Accent %s Highlight %s",
	     effectiveAppearanceName.UTF8String, accentName,
	     highlightName);
    Tk_SendVirtualEvent(tkwin, "AppearanceChanged", Tcl_NewStringObj(data, -1));
	event.name = Tk_GetUid("DarkAqua");
    } else {
        event.name = Tk_GetUid("LightAqua");
    }
    Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
}
}

- (void)observeValueForKeyPath:(NSString *)keyPath
		      ofObject:(id)object
			change:(NSDictionary *)change
		       context:(void *)context
{
    NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
    if (object == preferences && [keyPath isEqualToString:@"AppleHighlightColor"]) {
	if (@available(macOS 10.14, *)) {
	    [self viewDidChangeEffectiveAppearance];
	}
    }
}

#endif

/*
 * This is no-op on 10.7 and up because Apple has removed this widget, but we
 * are leaving it here for backwards compatibility.
 */

- (void) tkToolbarButton: (id) sender
{
#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd);
#endif
    XVirtualEvent event;
    int x, y;
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
    Tk_Window tkwin = (Tk_Window) winPtr;
    Tk_Window tkwin = (Tk_Window)winPtr;
    (void)sender;

    if (!winPtr){
	return;
    }
    bzero(&event, sizeof(XVirtualEvent));
    event.type = VirtualEvent;
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
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







+
+
-
+
-
-
-
-
-
+


















-
+
+







-
+







	    &event.x_root, &event.y_root, &x, &y, &event.state);
    Tk_TopCoordsToWindow(tkwin, x, y, &event.x, &event.y);
    event.same_screen = true;
    event.name = Tk_GetUid("ToolbarButton");
    Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
}

/*
 * On Catalina this is never called and drawRect clips to the rect that
- (BOOL) isOpaque
 * is passed to it by AppKit.
{
    NSWindow *w = [self window];
      return (w && (([w styleMask] & NSTexturedBackgroundWindowMask) ||
    	    ![w isOpaque]) ? NO : YES);
}
 */

- (BOOL) wantsDefaultClipping
{
    return NO;
}

- (BOOL) acceptsFirstResponder
{
    return YES;
}

/*
 * This keyDown method does nothing, which is a huge improvement over the
 * default keyDown method which beeps every time a key is pressed.
 */

- (void) keyDown: (NSEvent *) theEvent
{
	(void)theEvent;
    (void)theEvent;

#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif
}

/*
 * When the services menu is opened this is called for each Responder in
 * the Responder chain until a service provider is found.  The TkContentView
 * the Responder chain until a service provider is found.  The TKContentView
 * should be the first (and generally only) Responder in the chain.  We
 * return the TkServices object that was created in TkpInit.
 */

- (id)validRequestorForSendType:(NSString *)sendType
		     returnType:(NSString *)returnType
{

Changes to macosx/tkMacOSXWm.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







-
-
-
-
-
+
+
+
+
+







/*
 * 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 <[email protected]>
 * 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 <[email protected]>
 * 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"
179
180
181
182
183
184
185
186

187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
179
180
181
182
183
184
185

186
187
188
189
190
191
192
193
194







195
196
197
198
199
200
201







-
+








-
-
-
-
-
-
-







 */

static void TopLevelReqProc(ClientData dummy, Tk_Window tkwin);

static const Tk_GeomMgr wmMgrType = {
    "wm",			/* name */
    TopLevelReqProc,		/* requestProc */
    NULL,			/* lostSlaveProc */
    NULL,			/* lostContentProc */
};

/*
 * The following keeps state for Aqua dock icon bounce notification.
 */

static int tkMacOSXWmAttrNotifyVal = 0;

/*
 * Hash table for Mac Window -> TkWindow mapping.
 */

static Tcl_HashTable windowTable;
static int windowHashInit = false;

/*
 * Forward declarations for procedures defined in this file:
 */

static NSRect		InitialWindowBounds(TkWindow *winPtr,
			    NSWindow *macWindow);
static int		ParseGeometry(Tcl_Interp *interp, char *string,
316
317
318
319
320
321
322
323

324
325
326
327
328
329
330
309
310
311
312
313
314
315

316
317
318
319
320
321
322
323







-
+







static int		WmWinTabbingId(Tcl_Interp *interp, TkWindow *winPtr,
			    int objc, Tcl_Obj *const objv[]);
static int		WmWinAppearance(Tcl_Interp *interp, TkWindow *winPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		ApplyWindowAttributeFlagChanges(TkWindow *winPtr,
			    NSWindow *macWindow, UInt64 oldAttributes,
			    int oldFlags, int create, int initial);
static void		ApplyMasterOverrideChanges(TkWindow *winPtr,
static void		ApplyContainerOverrideChanges(TkWindow *winPtr,
			    NSWindow *macWindow);
static void		GetMinSize(TkWindow *winPtr, int *minWidthPtr,
			    int *minHeightPtr);
static void		GetMaxSize(TkWindow *winPtr, int *maxWidthPtr,
			    int *maxHeightPtr);
static void		RemapWindows(TkWindow *winPtr,
			    MacDrawable *parentWin);
356
357
358
359
360
361
362



363




364
365


366


367
368
369
370
371
372
373
349
350
351
352
353
354
355
356
357
358

359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376







+
+
+
-
+
+
+
+


+
+

+
+







}
#endif

@end

#pragma mark -

@implementation TKPanel: NSPanel
@synthesize tkWindow = _tkWindow;
@end
#pragma mark TKWindow(TKWm)

@implementation TKDrawerWindow: NSWindow
@synthesize tkWindow = _tkWindow;
@end

@implementation TKWindow: NSWindow
@synthesize mouseInResizeArea = _mouseInResizeArea;
@synthesize tkWindow = _tkWindow;
@end

#pragma mark TKWindow(TKWm)

@implementation TKWindow(TKWm)

/*
 * This method synchronizes Tk's understanding of the bounds of a contentView
 * with the window's.  It is needed because there are situations when the
 * window manager can change the layout of an NSWindow without having been
519
520
521
522
523
524
525
526

527
528
529
530
531
532
533
522
523
524
525
526
527
528

529
530
531
532
533
534
535
536







-
+







 *----------------------------------------------------------------------
 */

static void
SetWindowSizeLimits(
    TkWindow *winPtr)
{
    NSWindow *macWindow = TkMacOSXDrawableWindow(winPtr->window);
    NSWindow *macWindow = TkMacOSXGetNSWindowForDrawable(winPtr->window);
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int minWidth, minHeight, maxWidth, maxHeight, base;

    if (!macWindow) {
	return;
    }
    GetMinSize(winPtr, &minWidth, &minHeight);
667
668
669
670
671
672
673
674

675
676
677
678
679
680
681
670
671
672
673
674
675
676

677
678
679
680
681
682
683
684







-
+







{
    WmInfo *wmPtr = (WmInfo *)ckalloc(sizeof(WmInfo));

    wmPtr->winPtr = winPtr;
    wmPtr->reparent = None;
    wmPtr->titleUid = NULL;
    wmPtr->iconName = NULL;
    wmPtr->master = NULL;
    wmPtr->container = NULL;
    wmPtr->hints.flags = InputHint | StateHint;
    wmPtr->hints.input = True;
    wmPtr->hints.initial_state = NormalState;
    wmPtr->hints.icon_pixmap = None;
    wmPtr->hints.icon_window = None;
    wmPtr->hints.icon_x = wmPtr->hints.icon_y = 0;
    wmPtr->hints.icon_mask = None;
725
726
727
728
729
730
731
732

733
734
735
736
737
738
739
740





































































741
742
743
744
745
746
747
728
729
730
731
732
733
734

735
736
737
738
739
740
741
742

743
744
745
746
747
748
749
750
751
752
753
754
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







-
+







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







    UpdateVRootGeometry(wmPtr);

    /*
     * Tk must monitor structure events for top-level windows, in order to
     * detect size and position changes caused by window managers.
     */

    Tk_CreateEventHandler((Tk_Window) winPtr, StructureNotifyMask,
    Tk_CreateEventHandler((Tk_Window)winPtr, StructureNotifyMask,
	    TopLevelEventProc, winPtr);

    /*
     * Arrange for geometry requests to be reflected from the window to the
     * window manager.
     */

    Tk_ManageGeometry((Tk_Window) winPtr, &wmMgrType, (ClientData) 0);
    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 --
 *
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
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859

860
861
862
863
864
865
866
867







+
+















-
+








void
TkWmMapWindow(
    TkWindow *winPtr)		/* Top-level window that's about to be
				 * mapped. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    XEvent event;

    if (wmPtr->flags & WM_NEVER_MAPPED) {
	/*
	 * Create the underlying Mac window for this Tk window.
	 */

	if (!TkMacOSXHostToplevelExists(winPtr)) {
	    TkMacOSXMakeRealWindowExist(winPtr);
	}

	wmPtr->flags &= ~WM_NEVER_MAPPED;

	/*
	 * Generate configure event when we first map the window.
	 */

	TkGenWMConfigureEvent((Tk_Window) winPtr, wmPtr->x, wmPtr->y, -1, -1,
	TkGenWMConfigureEvent((Tk_Window)winPtr, wmPtr->x, wmPtr->y, -1, -1,
		TK_LOCATION_CHANGED);

	/*
	 * This is the first time this window has ever been mapped. Store all
	 * the window-manager-related information for the window.
	 */

828
829
830
831
832
833
834
835

836
837

838








839
840
841
842
843
844
845
901
902
903
904
905
906
907

908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927







-
+


+

+
+
+
+
+
+
+
+







    if (wmPtr->flags & WM_UPDATE_PENDING) {
	Tcl_CancelIdleCall(UpdateGeometryInfo, winPtr);
    }
    UpdateGeometryInfo(winPtr);
    wmPtr->flags &= ~WM_ABOUT_TO_MAP;

    /*
     * Map the window.
     * Map the window and process a MapNotify event for it.
     */

    winPtr->flags |= TK_MAPPED;
    XMapWindow(winPtr->display, winPtr->window);
    event.xany.serial = LastKnownRequestProcessed(winPtr->display);
    event.xany.send_event = False;
    event.xany.display = winPtr->display;
    event.xmap.window = winPtr->window;
    event.xmap.type = MapNotify;
    event.xmap.event = winPtr->window;
    event.xmap.override_redirect = winPtr->atts.override_redirect;
    TkpHandleMapOrUnmap((Tk_Window)winPtr, &event);
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmUnmapWindow --
 *
856
857
858
859
860
861
862










863

864
865
866
867
868
869
870
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963







+
+
+
+
+
+
+
+
+
+

+







 */

void
TkWmUnmapWindow(
    TkWindow *winPtr)		/* Top-level window that's about to be
				 * unmapped. */
{
    XEvent event;

    event.xany.serial = LastKnownRequestProcessed(winPtr->display);
    event.xany.send_event = False;
    event.xany.display = winPtr->display;
    event.xunmap.type = UnmapNotify;
    event.xunmap.window = winPtr->window;
    event.xunmap.event = winPtr->window;
    event.xunmap.from_configure = false;
    winPtr->flags &= ~TK_MAPPED;
    XUnmapWindow(winPtr->display, winPtr->window);
    TkpHandleMapOrUnmap((Tk_Window)winPtr, &event);
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmDeadWindow --
 *
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
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







-
+






-
+



-
-
+
+














-
+



-
+







 */

void
TkWmDeadWindow(
    TkWindow *winPtr)		/* Top-level window that's being deleted. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr, *wmPtr2;
    NSWindow *ourNSWindow;
    TKWindow *deadNSWindow;

    if (wmPtr == NULL) {
	return;
    }

    /*
     *If the dead window is a transient, remove it from the master's list.
     *If the dead window is a transient, remove it from the container's list.
     */

    RemoveTransient(winPtr);
    Tk_ManageGeometry((Tk_Window) winPtr, NULL, NULL);
    Tk_DeleteEventHandler((Tk_Window) winPtr, StructureNotifyMask,
    Tk_ManageGeometry((Tk_Window)winPtr, NULL, NULL);
    Tk_DeleteEventHandler((Tk_Window)winPtr, StructureNotifyMask,
	    TopLevelEventProc, winPtr);
    if (wmPtr->hints.flags & IconPixmapHint) {
	Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap);
    }
    if (wmPtr->hints.flags & IconMaskHint) {
	Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask);
    }
    if (wmPtr->iconName != NULL) {
	ckfree(wmPtr->iconName);
    }
    if (wmPtr->leaderName != NULL) {
	ckfree(wmPtr->leaderName);
    }
    if (wmPtr->icon != NULL) {
	wmPtr2 = ((TkWindow *) wmPtr->icon)->wmInfoPtr;
	wmPtr2 = ((TkWindow *)wmPtr->icon)->wmInfoPtr;
	wmPtr2->iconFor = NULL;
    }
    if (wmPtr->iconFor != NULL) {
	wmPtr2 = ((TkWindow *) wmPtr->iconFor)->wmInfoPtr;
	wmPtr2 = ((TkWindow *)wmPtr->iconFor)->wmInfoPtr;
	wmPtr2->icon = NULL;
	wmPtr2->hints.flags &= ~IconWindowHint;
    }
    while (wmPtr->protPtr != NULL) {
	ProtocolHandler *protPtr = wmPtr->protPtr;
	wmPtr->protPtr = protPtr->nextPtr;
	Tcl_EventuallyFree(protPtr, TCL_DYNAMIC);
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
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







-
+

-
+

-
+
















-
-
-
-
+
+
+
+

-
+




-
+




-
+




-
+







     * If the dead window has a transient, remove references to it from
     * the transient.
     */

    for (Transient *transientPtr = wmPtr->transientPtr;
	    transientPtr != NULL; transientPtr = transientPtr->nextPtr) {
    	TkWindow *winPtr2 = transientPtr->winPtr;
    	TkWindow *masterPtr = (TkWindow *) TkGetTransientMaster(winPtr2);
    	TkWindow *containerPtr = (TkWindow *)TkMacOSXGetContainer(winPtr2);

    	if (masterPtr == winPtr) {
    	if (containerPtr == winPtr) {
    	    wmPtr2 = winPtr2->wmInfoPtr;
    	    wmPtr2->master = NULL;
    	    wmPtr2->container = NULL;
    	}
    }

    while (wmPtr->transientPtr != NULL) {
	Transient *transientPtr = wmPtr->transientPtr;

	wmPtr->transientPtr = transientPtr->nextPtr;
	ckfree(transientPtr);
    }

    /*
     * Unregister the NSWindow and remove all references to it from the Tk
     * data structures.  If the NSWindow is a child, disassociate it from
     * the parent.  Then close and release the NSWindow.
     */

    ourNSWindow = wmPtr->window;
    if (ourNSWindow && !Tk_IsEmbedded(winPtr)) {
	NSWindow *parent = [ourNSWindow parentWindow];
	TkMacOSXUnregisterMacWindow(ourNSWindow);
    deadNSWindow = (TKWindow *)wmPtr->window;
    if (deadNSWindow && !Tk_IsEmbedded(winPtr)) {
	NSWindow *parent = [deadNSWindow parentWindow];
	[deadNSWindow setTkWindow:None];
        if (winPtr->window) {
            ((MacDrawable *) winPtr->window)->view = nil;
            ((MacDrawable *)winPtr->window)->view = nil;
        }
	wmPtr->window = NULL;

	if (parent) {
	    [parent removeChildWindow:ourNSWindow];
	    [parent removeChildWindow:deadNSWindow];
	}

#if DEBUG_ZOMBIES > 1
	{
	    const char *title = [[ourNSWindow title] UTF8String];
	    const char *title = [[deadNSWindow title] UTF8String];
	    if (title == nil) {
		title = "unnamed window";
	    }
	    fprintf(stderr, ">>>> Closing <%s>. Count is: %lu\n", title,
		    [ourNSWindow retainCount]);
		    [deadNSWindow retainCount]);
	}
#endif

	/*
	 * When a window is closed we want to move the focus to the next
	 * highest window.  Apple's documentation says that calling the
	 * orderOut method of the key window will accomplish this.  But
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
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







-
+









-
+



-
-
+
+








	    if (!winPtr2 || !winPtr2->wmInfoPtr) {
		continue;
	    }
	    wmPtr2 = winPtr2->wmInfoPtr;
	    isOnScreen = (wmPtr2->hints.initial_state != IconicState &&
			  wmPtr2->hints.initial_state != WithdrawnState);
	    if (w != ourNSWindow && isOnScreen && [w canBecomeKeyWindow]) {
	    if (w != deadNSWindow && isOnScreen && [w canBecomeKeyWindow]) {
		[w makeKeyAndOrderFront:NSApp];
		break;
	    }
	}

	/*
	 * Prevent zombies on systems with a TouchBar.
	 */

	if (ourNSWindow == [NSApp keyWindow]) {
	if (deadNSWindow == [NSApp keyWindow]) {
	    [NSApp _setKeyWindow:nil];
	    [NSApp _setMainWindow:nil];
	}
	[ourNSWindow close];
	[ourNSWindow release];
	[deadNSWindow close];
	[deadNSWindow release];
	[NSApp _resetAutoreleasePool];

#if DEBUG_ZOMBIES > 1
	fprintf(stderr, "================= Pool dump ===================\n");
	[NSAutoreleasePool showPools];
#endif

1090
1091
1092
1093
1094
1095
1096
1097

1098
1099
1100
1101
1102
1103
1104
1183
1184
1185
1186
1187
1188
1189

1190
1191
1192
1193
1194
1195
1196
1197







-
+







int
Tk_WmObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window) clientData;
    Tk_Window tkwin = (Tk_Window)clientData;
    static const char *const optionStrings[] = {
	"aspect", "attributes", "client", "colormapwindows",
	"command", "deiconify", "focusmodel", "forget",
	"frame", "geometry", "grid", "group",
	"iconbitmap", "iconify", "iconmask", "iconname",
	"iconphoto", "iconposition", "iconwindow",
	"manage", "maxsize", "minsize", "overrideredirect",
1429
1430
1431
1432
1433
1434
1435
1436

1437
1438
1439
1440
1441
1442
1443
1522
1523
1524
1525
1526
1527
1528

1529
1530
1531
1532
1533
1534
1535
1536







-
+







		wmPtr->flags &= ~WM_TRANSPARENT;
		wmPtr->attributes &= ~kWindowNoShadowAttribute;
	    }
	    ApplyWindowAttributeFlagChanges(winPtr, macWindow, oldAttributes,
		    oldFlags, 1, 0);
	    [macWindow setBackgroundColor:boolean ? [NSColor clearColor] : nil];
	    [macWindow setOpaque:!boolean];
	    TkMacOSXInvalidateWindow((MacDrawable *) winPtr->window,
	    TkMacOSXInvalidateWindow((MacDrawable *)winPtr->window,
		    TK_PARENT_WINDOW);
	    }
	break;
    case WMATT_TYPE:
	TKLog(@"The type attribute is ignored on macOS.");
	break;
    case _WMATT_LAST_ATTRIBUTE:
1525
1526
1527
1528
1529
1530
1531
1532

1533
1534
1535
1536
1537

1538
1539
1540
1541
1542
1543
1544
1618
1619
1620
1621
1622
1623
1624

1625
1626
1627
1628
1629

1630
1631
1632
1633
1634
1635
1636
1637







-
+




-
+







    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int attribute = 0;
    NSWindow *macWindow;

    if (winPtr->window == None) {
	Tk_MakeWindowExist((Tk_Window) winPtr);
	Tk_MakeWindowExist((Tk_Window)winPtr);
    }
    if (!TkMacOSXHostToplevelExists(winPtr)) {
	TkMacOSXMakeRealWindowExist(winPtr);
    }
    macWindow = TkMacOSXDrawableWindow(winPtr->window);
    macWindow = TkMacOSXGetNSWindowForDrawable(winPtr->window);

    if (objc == 3) {		/* wm attributes $win */
	Tcl_Obj *result = Tcl_NewObj();

	for (attribute = 0; attribute < _WMATT_LAST_ATTRIBUTE; ++attribute) {
	    Tcl_ListObjAppendElement(NULL, result,
		    Tcl_NewStringObj(WmAttributeNames[attribute], -1));
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
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







-
+







-
+



















-
+


















-
+







    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);
	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,
		    TkNewWindowObj((Tk_Window) wmPtr->cmapList[i]));
		    Tk_NewWindowObj((Tk_Window)wmPtr->cmapList[i]));
	}
	Tcl_SetObjResult(interp, resultObj);
	return TCL_OK;
    }
    if (Tcl_ListObjGetElements(interp, objv[3], &windowObjc, &windowObjv)
	    != TCL_OK) {
	return TCL_ERROR;
    }
    cmapList = (TkWindow **)ckalloc((windowObjc+1) * sizeof(TkWindow*));
    for (i = 0; i < windowObjc; i++) {
	if (TkGetWindowFromObj(interp, tkwin, windowObjv[i],
		(Tk_Window *) &winPtr2) != TCL_OK) {
	    ckfree(cmapList);
	    return TCL_ERROR;
	}
	if (winPtr2 == winPtr) {
	    gotToplevel = 1;
	}
	if (winPtr2->window == None) {
	    Tk_MakeWindowExist((Tk_Window) winPtr2);
	    Tk_MakeWindowExist((Tk_Window)winPtr2);
	}
	cmapList[i] = winPtr2;
    }
    if (!gotToplevel) {
	wmPtr->flags |= WM_ADDED_TOPLEVEL_COLORMAP;
	cmapList[windowObjc] = winPtr;
	windowObjc++;
    } else {
	wmPtr->flags &= ~WM_ADDED_TOPLEVEL_COLORMAP;
    }
    wmPtr->flags |= WM_COLORMAPS_EXPLICIT;
    if (wmPtr->cmapList != NULL) {
	ckfree(wmPtr->cmapList);
    }
    wmPtr->cmapList = cmapList;
    wmPtr->cmapCount = windowObjc;

    /*
     * On the Macintosh all of this is just an excercise in compatability as
     * 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;
}

/*
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
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







-
+





-


















-
+






-
+






-
+

-
+

-
+

-
+







    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    NSWindow *win = TkMacOSXDrawableWindow(winPtr->window);
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(winPtr->window);

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }

    if (wmPtr->iconFor != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't deiconify %s: it is an icon for %s",
		Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	Tcl_SetErrorCode(interp, "TK", "WM", "DEICONIFY", "ICON", NULL);
	return TCL_ERROR;
    } else if (winPtr->flags & TK_EMBEDDED) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't deiconify %s: it is an embedded window",
		winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "WM", "DEICONIFY", "EMBEDDED", NULL);
	return TCL_ERROR;
    }

    TkpWmSetState(winPtr, TkMacOSXIsWindowZoomed(winPtr) ?
	    ZoomState : NormalState);
    [win setExcludedFromWindowsMenu:NO];
    TkMacOSXApplyWindowAttributes(winPtr, win);
    [win orderFront:nil];
    [win orderFront:NSApp];
    if (wmPtr->icon) {
	Tk_UnmapWindow((Tk_Window)wmPtr->icon);
    }

    /*
     * If this window has a transient, the transient must also be deiconified if
     * it was withdrawn by the master.
     * it was withdrawn by the container.
     */

    for (Transient *transientPtr = wmPtr->transientPtr;
	    transientPtr != NULL; transientPtr = transientPtr->nextPtr) {
	TkWindow *winPtr2 = transientPtr->winPtr;
	WmInfo *wmPtr2 = winPtr2->wmInfoPtr;
	TkWindow *masterPtr = (TkWindow *) TkGetTransientMaster(winPtr2);
	TkWindow *containerPtr = (TkWindow *)TkMacOSXGetContainer(winPtr2);

    	if (masterPtr == winPtr) {
    	if (containerPtr == winPtr) {
	    if ((wmPtr2->hints.initial_state == WithdrawnState) &&
		    ((transientPtr->flags & WITHDRAWN_BY_MASTER) != 0)) {
		    ((transientPtr->flags & WITHDRAWN_BY_CONTAINER) != 0)) {
		TkpWmSetState(winPtr2, NormalState);
		transientPtr->flags &= ~WITHDRAWN_BY_MASTER;
		transientPtr->flags &= ~WITHDRAWN_BY_CONTAINER;
	    }
	}
    }

    return TCL_OK;
}

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
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







-
+







-
+










-
+







WmForgetCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel or Frame to work with */
    TCL_UNUSED(Tcl_Interp *),	/* Current interpreter. */
    TCL_UNUSED(int),			/* Number of arguments. */
    TCL_UNUSED(Tcl_Obj *const *))	/* Argument objects. */
{
    Tk_Window frameWin = (Tk_Window) winPtr;
    Tk_Window frameWin = (Tk_Window)winPtr;

    if (Tk_IsTopLevel(frameWin)) {
	MacDrawable *macWin;

	Tk_MakeWindowExist(frameWin);
	Tk_MakeWindowExist((Tk_Window)winPtr->parentPtr);

	macWin = (MacDrawable *) winPtr->window;
	macWin = (MacDrawable *)winPtr->window;

    	TkFocusJoin(winPtr);
    	Tk_UnmapWindow(frameWin);

	macWin->toplevel->referenceCount--;
	macWin->toplevel = winPtr->parentPtr->privatePtr->toplevel;
	macWin->toplevel->referenceCount++;
	macWin->flags &= ~TK_HOST_EXISTS;

	TkWmDeadWindow(winPtr);
	RemapWindows(winPtr, (MacDrawable *) winPtr->parentPtr->window);
	RemapWindows(winPtr, (MacDrawable *)winPtr->parentPtr->window);

        /*
         * Make sure wm no longer manages this window
         */
        Tk_ManageGeometry(frameWin, NULL, NULL);

	winPtr->flags &= ~(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED);
2004
2005
2006
2007
2008
2009
2010
2011

2012
2013
2014
2015
2016
2017
2018
2096
2097
2098
2099
2100
2101
2102

2103
2104
2105
2106
2107
2108
2109
2110







-
+








    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    window = wmPtr->reparent;
    if (window == None) {
	window = Tk_WindowId((Tk_Window) winPtr);
	window = Tk_WindowId((Tk_Window)winPtr);
    }
    sprintf(buf, "0x%" TCL_Z_MODIFIER "x", (size_t)window);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
    return TCL_OK;
}

/*
2037
2038
2039
2040
2041
2042
2043
2044

2045
2046
2047
2048
2049
2050
2051
2129
2130
2131
2132
2133
2134
2135

2136
2137
2138
2139
2140
2141
2142
2143







-
+







    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    NSWindow *win = TkMacOSXDrawableWindow(winPtr->window);
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(winPtr->window);
    char xSign = '+', ySign = '+';
    int width, height, x = wmPtr->x, y= wmPtr->y;
    char *argv3;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newGeometry?");
	return TCL_ERROR;
2163
2164
2165
2166
2167
2168
2169
2170

2171
2172
2173
2174
2175
2176
2177
2255
2256
2257
2258
2259
2260
2261

2262
2263
2264
2265
2266
2267
2268
2269







-
+







	} else if (widthInc <= 0) {
	    errorMsg = "widthInc can't be <= 0";
	    goto error;
	} else if (heightInc <= 0) {
	    errorMsg = "heightInc can't be <= 0";
	    goto error;
	}
	Tk_SetGrid((Tk_Window) winPtr, reqWidth, reqHeight, widthInc,
	Tk_SetGrid((Tk_Window)winPtr, reqWidth, reqHeight, widthInc,
		heightInc);
    }
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;

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







-
+




-
+









-
+







		    Tk_NameOfBitmap(winPtr->display,wmPtr->hints.icon_pixmap),
		    -1));
	}
	return TCL_OK;
    }
    str = Tcl_GetStringFromObj(objv[3], &len);
    if (winPtr->window == None) {
	Tk_MakeWindowExist((Tk_Window) winPtr);
	Tk_MakeWindowExist((Tk_Window)winPtr);
    }
    if (!TkMacOSXHostToplevelExists(winPtr)) {
	TkMacOSXMakeRealWindowExist(winPtr);
    }
    if (WmSetAttribute(winPtr, TkMacOSXDrawableWindow(winPtr->window), interp,
    if (WmSetAttribute(winPtr, TkMacOSXGetNSWindowForDrawable(winPtr->window), interp,
	    WMATT_TITLEPATH, objv[3]) == TCL_OK) {
	if (!len) {
	    if (wmPtr->hints.icon_pixmap != None) {
		Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap);
		wmPtr->hints.icon_pixmap = None;
	    }
	    wmPtr->hints.flags &= ~IconPixmapHint;
	}
    } else {
	pixmap = Tk_GetBitmap(interp, (Tk_Window) winPtr, Tk_GetUid(str));
	pixmap = Tk_GetBitmap(interp, (Tk_Window)winPtr, Tk_GetUid(str));
	if (pixmap == None) {
	    return TCL_ERROR;
	}
	wmPtr->hints.icon_pixmap = pixmap;
	wmPtr->hints.flags |= IconPixmapHint;
    }
    return TCL_OK;
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
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







-
+






-
+






-
+





-
+












-
+





-
-
+
+


-
+







{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }

    if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
    if (Tk_Attributes((Tk_Window)winPtr)->override_redirect) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't iconify \"%s\": override-redirect flag is set",
		winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "OVERRIDE_REDIRECT",
		NULL);
	return TCL_ERROR;
    } else if (wmPtr->master != NULL) {
    } 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) {
	Tk_MapWindow((Tk_Window)wmPtr->icon);
    }

    /*
     * If this window has a transient the transient must be withdrawn when
     * the master is iconified.
     * the container is iconified.
     */

    for (Transient *transientPtr = wmPtr->transientPtr;
	    transientPtr != NULL; transientPtr = transientPtr->nextPtr) {
	TkWindow *winPtr2 = transientPtr->winPtr;
	TkWindow *masterPtr = (TkWindow *) TkGetTransientMaster(winPtr2);
    	if (masterPtr == winPtr &&
	TkWindow *containerPtr = (TkWindow *)TkMacOSXGetContainer(winPtr2);
    	if (containerPtr == winPtr &&
		winPtr2->wmInfoPtr->hints.initial_state != WithdrawnState) {
	    TkpWmSetState(winPtr2, WithdrawnState);
	    transientPtr->flags |= WITHDRAWN_BY_MASTER;
	    transientPtr->flags |= WITHDRAWN_BY_CONTAINER;
	}
    }

    return TCL_OK;
}

/*
2578
2579
2580
2581
2582
2583
2584
2585

2586
2587
2588
2589
2590
2591
2592
2670
2671
2672
2673
2674
2675
2676

2677
2678
2679
2680
2681
2682
2683
2684







-
+







	      icon));
	Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "PHOTO", NULL);
	return TCL_ERROR;
    }

    Tk_SizeOfImage(tk_icon, &width, &height);
    if (width != 0 && height != 0) {
	newIcon = TkMacOSXGetNSImageWithTkImage(winPtr->display, tk_icon,
	newIcon = TkMacOSXGetNSImageFromTkImage(winPtr->display, tk_icon,
						width, height);
    }
    Tk_FreeImage(tk_icon);
    if (newIcon == NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "failed to create an iconphoto with image \"%s\"", icon));
	Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "IMAGE", NULL);
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
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







-
+







-
+
















-
+










-
+














-
+







    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, TkNewWindowObj(wmPtr->icon));
	    Tcl_SetObjResult(interp, Tk_NewWindowObj(wmPtr->icon));
	}
	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->hints.flags &= ~IconWindowHint;
	if (wmPtr->icon != NULL) {
	    wmPtr2 = ((TkWindow *) wmPtr->icon)->wmInfoPtr;
	    wmPtr2 = ((TkWindow *)wmPtr->icon)->wmInfoPtr;
	    wmPtr2->iconFor = NULL;
	    wmPtr2->hints.initial_state = WithdrawnState;
	}
	wmPtr->icon = NULL;
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (!Tk_IsTopLevel(tkwin2)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't use %s as icon window: not at top level",
		    Tk_PathName(tkwin2)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONWINDOW", "TOPLEVEL",
		    NULL);
	    return TCL_ERROR;
	}
	wmPtr2 = ((TkWindow *) tkwin2)->wmInfoPtr;
	wmPtr2 = ((TkWindow *)tkwin2)->wmInfoPtr;
	if (wmPtr2->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "%s is already an icon for %s",
		    Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONWINDOW", "ICON", NULL);
	    return TCL_ERROR;
	}
	if (wmPtr->icon != NULL) {
	    TkWindow *oldIcon = (TkWindow *)wmPtr->icon;
	    WmInfo *wmPtr3 = oldIcon->wmInfoPtr;
	    NSWindow *win = TkMacOSXDrawableWindow(oldIcon->window);
	    NSWindow *win = TkMacOSXGetNSWindowForDrawable(oldIcon->window);

	    /*
	     * The old icon should be withdrawn.
	     */

	    TkpWmSetState(oldIcon, WithdrawnState);
	    [win orderOut:nil];
    	    [win setExcludedFromWindowsMenu:YES];
	    wmPtr3->iconFor = NULL;
	}
	Tk_MakeWindowExist(tkwin2);
	wmPtr->hints.icon_window = Tk_WindowId(tkwin2);
	wmPtr->hints.flags |= IconWindowHint;
	wmPtr->icon = tkwin2;
	wmPtr2->iconFor = (Tk_Window) winPtr;
	wmPtr2->iconFor = (Tk_Window)winPtr;
	if (!(wmPtr2->flags & WM_NEVER_MAPPED)) {
	    /*
	     * If the window is in normal or zoomed state, the icon should be
	     * unmapped.
	     */

	    if (wmPtr->hints.initial_state == NormalState ||
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
2864
2865
2866
2867
2868
2869
2870



2871
2872
2873
2874
2875
2876

2877
2878
2879
2880

2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907


2908
2909
2910
2911
2912
2913
2914
2915
2916







-
-
-
+
+
+



-
+



-
+









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





-
-
+
+







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmManageCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,           /* Toplevel or Frame to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    TCL_UNUSED(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;
    Tk_Window frameWin = (Tk_Window)winPtr;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (!Tk_IsTopLevel(frameWin)) {
	MacDrawable *macWin = (MacDrawable *) winPtr->window;
	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;
		Tk_MakeWindowExist((Tk_Window)winPtr);
		macWin = (MacDrawable *)winPtr->window;
	    }
	}
	wmPtr = winPtr->wmInfoPtr;
	winPtr->flags &= ~TK_MAPPED;
	macWin->toplevel->referenceCount--;
	macWin->toplevel = macWin;
	macWin->toplevel->referenceCount++;
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
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







-
+







-
-
+
+







-
-
+
+







    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int flag;
    XSetWindowAttributes atts;
    TKWindow *win = (TKWindow *)TkMacOSXDrawableWindow(winPtr->window);
    TKWindow *win = (TKWindow *)TkMacOSXGetNSWindowForDrawable(winPtr->window);

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
		Tk_Attributes((Tk_Window) winPtr)->override_redirect != 0));
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
		Tk_Attributes((Tk_Window) winPtr)->override_redirect));
	return TCL_OK;
    }

    if (Tcl_GetBooleanFromObj(interp, objv[3], &flag) != TCL_OK) {
	return TCL_ERROR;
    }
    atts.override_redirect = flag ? True : False;
    Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect, &atts);
    ApplyMasterOverrideChanges(winPtr, win);
    Tk_ChangeWindowAttributes((Tk_Window)winPtr, CWOverrideRedirect, &atts);
    ApplyContainerOverrideChanges(winPtr, win);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmPositionfromCmd --
3092
3093
3094
3095
3096
3097
3098
3099

3100
3101
3102
3103
3104
3105
3106
3196
3197
3198
3199
3200
3201
3202

3203
3204
3205
3206
3207
3208
3209
3210







-
+







	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    Tk_GetAtomName((Tk_Window)winPtr, protPtr->protocol),-1));
	}
	Tcl_SetObjResult(interp, resultObj);
	return TCL_OK;
    }

    protocol = Tk_InternAtom((Tk_Window) winPtr, Tcl_GetString(objv[3]));
    protocol = Tk_InternAtom((Tk_Window)winPtr, Tcl_GetString(objv[3]));
    if (objc == 4) {
	/*
	 * Return the command to handle a given protocol.
	 */

	for (protPtr = wmPtr->protPtr; protPtr != NULL;
		protPtr = protPtr->nextPtr) {
3332
3333
3334
3335
3336
3337
3338
3339

3340
3341
3342
3343
3344
3345
3346
3436
3437
3438
3439
3440
3441
3442

3443
3444
3445
3446
3447
3448
3449
3450







-
+








    if (objc == 3) {
	windows = TkWmStackorderToplevel(winPtr);
	if (windows != NULL) {
	    resultObj = Tcl_NewObj();
	    for (windowPtr = windows; *windowPtr ; windowPtr++) {
		Tcl_ListObjAppendElement(NULL, resultObj,
		    TkNewWindowObj((Tk_Window) *windowPtr));
			Tk_NewWindowObj((Tk_Window)*windowPtr));
	    }
	    Tcl_SetObjResult(interp, resultObj);
	    ckfree(windows);
	    return TCL_OK;
	} else {
	    return TCL_ERROR;
	}
3452
3453
3454
3455
3456
3457
3458
3459

3460
3461
3462
3463
3464
3465
3466

3467
3468
3469
3470
3471
3472
3473
3556
3557
3558
3559
3560
3561
3562

3563
3564
3565
3566
3567
3568
3569

3570
3571
3572
3573
3574
3575
3576
3577







-
+






-
+







	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) {
3481
3482
3483
3484
3485
3486
3487
3488

3489
3490
3491
3492
3493
3494
3495
3496

3497
3498
3499
3500
3501
3502
3503
3585
3586
3587
3588
3589
3590
3591

3592
3593
3594
3595
3596
3597
3598
3599

3600
3601
3602
3603
3604
3605
3606
3607







-
+







-
+







	    /*
	     * This varies from 'wm deiconify' because it does not force the
	     * window to be raised and receive focus
	     */

	    break;
	case OPT_ICONIC:
	    if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
	    if (Tk_Attributes((Tk_Window)winPtr)->override_redirect) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't iconify \"%s\": override-redirect flag is set",
			winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "STATE",
			"OVERRIDE_REDIRECT", NULL);
		return TCL_ERROR;
	    }
	    if (wmPtr->master != NULL) {
	    if (wmPtr->container != NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't iconify \"%s\": it is a transient",
			winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "STATE", "TRANSIENT",
			NULL);
		return TCL_ERROR;
	    }
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
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







-
-
+
+




-
+



-
+

-
+






-
+


-
-
+
+

-
+


-
+

-
+









-
+







-
+





-
-
+
+


-
-
+
+






-
+














-
+






-
+


-
+

-
+








-
-
+
+





-
-
+
+










-
+


-
+


-
-
+
+



-
+







    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window master;
    TkWindow *masterPtr, *w;
    Tk_Window container;
    TkWindow *containerPtr, *w;
    WmInfo *wmPtr2;
    Transient *transient;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?master?");
	Tcl_WrongNumArgs(interp, 2, objv, "window ?window?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->master != NULL) {
	if (wmPtr->container != NULL) {
	    Tcl_SetObjResult(interp,
		Tcl_NewStringObj(Tk_PathName(wmPtr->master), -1));
		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], &master) != TCL_OK) {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &container) != TCL_OK) {
	    return TCL_ERROR;
	}
	masterPtr = (TkWindow*) master;
	while (!Tk_TopWinHierarchy(masterPtr)) {
	containerPtr = (TkWindow*) container;
	while (!Tk_TopWinHierarchy(containerPtr)) {
            /*
             * Ensure that the master window is actually a Tk toplevel.
             * Ensure that the container window is actually a Tk toplevel.
             */

            masterPtr = masterPtr->parentPtr;
            containerPtr = containerPtr->parentPtr;
        }
	Tk_MakeWindowExist((Tk_Window)masterPtr);
	Tk_MakeWindowExist((Tk_Window)containerPtr);

	if (wmPtr->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't make \"%s\" a transient: it is an icon for %s",
		    Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
	    return TCL_ERROR;
	}

	wmPtr2 = masterPtr->wmInfoPtr;
	wmPtr2 = containerPtr->wmInfoPtr;

	/*
	 * Under some circumstances, wmPtr2 is NULL here.
	 */

	if (wmPtr2 != NULL && wmPtr2->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't make \"%s\" a master: it is an icon for %s",
		    "can't make \"%s\" a container: it is an icon for %s",
		    Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
	    return TCL_ERROR;
	}

	for (w = masterPtr; w != NULL && w->wmInfoPtr != NULL;
		w = (TkWindow *)w->wmInfoPtr->master) {
	for (w = containerPtr; w != NULL && w->wmInfoPtr != NULL;
		w = (TkWindow *)w->wmInfoPtr->container) {
	    if (w == winPtr) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "setting \"%s\" as master creates a transient/master cycle",
		    Tk_PathName(masterPtr)));
		    "can't set \"%s\" as container: would cause management loop",
		    Tk_PathName(containerPtr)));
		Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
		return TCL_ERROR;
	    }
	}

	/*
	 * Add the transient to the master's list, if it not already there.
	 * Add the transient to the container's list, if it not already there.
	 */

	for (transient = wmPtr2->transientPtr;
	     transient != NULL && transient->winPtr != winPtr;
	     transient = transient->nextPtr) {}
	if (transient == NULL) {
	    transient = (Transient *)ckalloc(sizeof(Transient));
	    transient->winPtr = winPtr;
	    transient->flags = 0;
	    transient->nextPtr = wmPtr2->transientPtr;
	    wmPtr2->transientPtr = transient;
	}

	/*
	 * If the master is withdrawn or iconic then withdraw the transient.
	 * If the container is withdrawn or iconic then withdraw the transient.
	 */

	if ((wmPtr2->hints.initial_state == WithdrawnState ||
		wmPtr2->hints.initial_state == IconicState) &&
		wmPtr->hints.initial_state != WithdrawnState) {
	    TkpWmSetState(winPtr, WithdrawnState);
	    transient->flags |= WITHDRAWN_BY_MASTER;
	    transient->flags |= WITHDRAWN_BY_CONTAINER;
	}

	wmPtr->master = (Tk_Window) masterPtr;
	wmPtr->container = (Tk_Window)containerPtr;
    }
    ApplyMasterOverrideChanges(winPtr, NULL);
    ApplyContainerOverrideChanges(winPtr, NULL);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * RemoveTransient --
 *
 *      Clears the transient's master record and removes the transient from the
 *      master's list.
 *      Clears the transient's container record and removes the transient from the
 *      container's list.
 *
 * Results:
 *	None
 *
 * Side effects:
 *      References to a master are removed from the transient's wmInfo
 *	structure and references to the transient are removed from its master's
 *      References to a container are removed from the transient's wmInfo
 *	structure and references to the transient are removed from its container's
 *	wmInfo.
 *
 *----------------------------------------------------------------------
 */

static void
RemoveTransient(
    TkWindow *winPtr)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr, *wmPtr2;
    TkWindow *masterPtr;
    TkWindow *containerPtr;
    Transient *transPtr, *temp;

    if (wmPtr == NULL || wmPtr->master == NULL) {
    if (wmPtr == NULL || wmPtr->container == NULL) {
	return;
    }
    masterPtr = (TkWindow *)wmPtr->master;
    wmPtr2 = masterPtr->wmInfoPtr;
    containerPtr = (TkWindow *)wmPtr->container;
    wmPtr2 = containerPtr->wmInfoPtr;
    if (wmPtr2 == NULL) {
	return;
    }
    wmPtr->master = NULL;
    wmPtr->container= NULL;
    transPtr = wmPtr2->transientPtr;
    while (transPtr != NULL) {
	if (transPtr->winPtr != winPtr) {
	    break;
	}
	temp = transPtr->nextPtr;
	ckfree(transPtr);
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
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







-
-
-
-







-
+

-
+


-
+







		Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	Tcl_SetErrorCode(interp, "TK", "WM", "WITHDRAW", "ICON", NULL);
	return TCL_ERROR;
    }

    TkpWmSetState(winPtr, WithdrawnState);

    NSWindow *win = TkMacOSXDrawableWindow(winPtr->window);
    [win orderOut:NSApp];
    [win setExcludedFromWindowsMenu:YES];

    /*
     * If this window has a transient, the transient must also be withdrawn.
     */

    for (Transient *transientPtr = wmPtr->transientPtr;
	    transientPtr != NULL; transientPtr = transientPtr->nextPtr) {
	TkWindow *winPtr2 = transientPtr->winPtr;
	TkWindow *masterPtr = (TkWindow *) TkGetTransientMaster(winPtr2);
	TkWindow *containerPtr = (TkWindow *)TkMacOSXGetContainer(winPtr2);

    	if (masterPtr == winPtr &&
    	if (containerPtr == winPtr &&
		winPtr2->wmInfoPtr->hints.initial_state != WithdrawnState) {
	    TkpWmSetState(winPtr2, WithdrawnState);
	    transientPtr->flags |= WITHDRAWN_BY_MASTER;
	    transientPtr->flags |= WITHDRAWN_BY_CONTAINER;
	}
    }

    return TCL_OK;
}

/*
3875
3876
3877
3878
3879
3880
3881
3882

3883
3884
3885
3886
3887
3888
3889
3975
3976
3977
3978
3979
3980
3981

3982
3983
3984
3985
3986
3987
3988
3989







-
+







    int reqWidth,		/* Width (in grid units) corresponding to the
				 * requested geometry for tkwin. */
    int reqHeight,		/* Height (in grid units) corresponding to the
				 * requested geometry for tkwin. */
    int widthInc, int heightInc)/* Pixel increments corresponding to a change
				 * of one grid unit. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *winPtr = (TkWindow *)tkwin;
    WmInfo *wmPtr;

    /*
     * Ensure widthInc and heightInc are greater than 0
     */

    if (widthInc <= 0) {
3969
3970
3971
3972
3973
3974
3975
3976

3977
3978
3979
3980
3981
3982
3983
4069
4070
4071
4072
4073
4074
4075

4076
4077
4078
4079
4080
4081
4082
4083







-
+







 */

void
Tk_UnsetGrid(
    Tk_Window tkwin)		/* Token for window that is currently
				 * controlling gridding. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *winPtr = (TkWindow *)tkwin;
    WmInfo *wmPtr;

    /*
     * Find the top-level window for tkwin, plus the window manager
     * information.
     */

4042
4043
4044
4045
4046
4047
4048
4049

4050
4051
4052
4053
4054
4055
4056

4057
4058
4059
4060
4061
4062
4063
4142
4143
4144
4145
4146
4147
4148

4149
4150
4151
4152
4153
4154
4155

4156
4157
4158
4159
4160
4161
4162
4163







-
+






-
+







	     * Tk_DestroyWindow will try to destroy the window, but of course
	     * it's already gone.
	     */

	    Tk_ErrorHandler handler = Tk_CreateErrorHandler(winPtr->display,
		    -1, -1, -1, NULL, NULL);

	    Tk_DestroyWindow((Tk_Window) winPtr);
	    Tk_DestroyWindow((Tk_Window)winPtr);
	    Tk_DeleteErrorHandler(handler);
	}
	if (wmTracing) {
	    TkMacOSXDbgMsg("TopLevelEventProc: %s deleted", winPtr->pathName);
	}
    } else if (eventPtr->type == ReparentNotify) {
	Tcl_Panic("recieved unwanted reparent event");
	Tcl_Panic("received unwanted reparent event");
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TopLevelReqProc --
4076
4077
4078
4079
4080
4081
4082
4083

4084
4085
4086
4087
4088
4089
4090
4176
4177
4178
4179
4180
4181
4182

4183
4184
4185
4186
4187
4188
4189
4190







-
+







 */

static void
TopLevelReqProc(
    TCL_UNUSED(void *),		/* Not used. */
    Tk_Window tkwin)		/* Information about window. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *winPtr = (TkWindow *)tkwin;
    WmInfo *wmPtr;

    wmPtr = winPtr->wmInfoPtr;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
4256
4257
4258
4259
4260
4261
4262
4263

4264
4265
4266
4267
4268
4269
4270
4356
4357
4358
4359
4360
4361
4362

4363
4364
4365
4366
4367
4368
4369
4370







-
+







	     * geometry, except to make sure that the desired size is known by
	     * the container. Also, zero out any position information, since
	     * embedded windows are not allowed to move.
	     */

	    wmPtr->x = wmPtr->y = 0;
	    wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y);
	    Tk_GeometryRequest((Tk_Window) contWinPtr, width, height);
	    Tk_GeometryRequest((Tk_Window)contWinPtr, width, height);
	}
	return;
    }
    if (wmPtr->flags & WM_MOVE_PENDING) {
	wmPtr->configWidth = width;
	wmPtr->configHeight = height;
	if (wmTracing) {
4509
4510
4511
4512
4513
4514
4515
4516

4517
4518
4519
4520
4521
4522
4523
4609
4610
4611
4612
4613
4614
4615

4616
4617
4618
4619
4620
4621
4622
4623







-
+







void
Tk_GetRootCoords(
    Tk_Window tkwin,		/* Token for window. */
    int *xPtr,			/* Where to store x-displacement of (0,0). */
    int *yPtr)			/* Where to store y-displacement of (0,0). */
{
    int x, y;
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *winPtr = (TkWindow *)tkwin;

    /*
     * Search back through this window's parents all the way to a top-level
     * window, combining the offsets of each window within its parent.
     */

    x = y = 0;
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
4631
4632
4633
4634
4635
4636
4637





















4638
4639
4640
4641
4642
4643
4644







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







		x += winPtr->wmInfoPtr->xInParent;
		y += winPtr->wmInfoPtr->yInParent;
		break;
	    }

	    otherPtr = TkpGetOtherWindow(winPtr);
	    if (otherPtr == NULL) {
		if (tkMacOSXEmbedHandler->getOffsetProc != NULL) {
		    Point theOffset;

		    /*
		     * We do not require that the changes.x & changes.y for a
		     * non-Tk master window be kept up to date. So we first
		     * subtract off the possibly bogus values that have been
		     * added on at the top of this pass through the loop, and
		     * then call out to the getOffsetProc to give us the
		     * correct offset.
		     */

		    x -= winPtr->changes.x + winPtr->changes.border_width;
		    y -= winPtr->changes.y + winPtr->changes.border_width;

		    tkMacOSXEmbedHandler->getOffsetProc((Tk_Window) winPtr,
			    &theOffset);

		    x += theOffset.h;
		    y += theOffset.v;
		}
		break;
	    }

	    /*
	     * The container window is in the same application. Query its
	     * coordinates.
	     */
4673
4674
4675
4676
4677
4678
4679
4680

4681
4682
4683

4684
4685
4686
4687
4688
4689
4690
4752
4753
4754
4755
4756
4757
4758

4759
4760
4761

4762
4763
4764
4765
4766
4767
4768
4769







-
+


-
+







	    }
	}
	if (nextPtr == NULL) {
	    break;
	}
	winPtr = nextPtr;
    }
    if (winPtr->mainPtr != ((TkWindow *) tkwin)->mainPtr) {
    if (winPtr->mainPtr != ((TkWindow *)tkwin)->mainPtr) {
	return NULL;
    }
    return (Tk_Window) winPtr;
    return (Tk_Window)winPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_TopCoordsToWindow --
 *
4716
4717
4718
4719
4720
4721
4722
4723

4724
4725
4726
4727
4728
4729
4730
4795
4796
4797
4798
4799
4800
4801

4802
4803
4804
4805
4806
4807
4808
4809







-
+







{
    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;
    winPtr = (TkWindow *)tkwin;
    x = rootX;
    y = rootY;
    while (1) {
	nextPtr = NULL;
	children = NULL;

	/*
4769
4770
4771
4772
4773
4774
4775
4776

4777
4778
4779
4780
4781
4782
4783
4848
4849
4850
4851
4852
4853
4854

4855
4856
4857
4858
4859
4860
4861
4862







-
+







	}
	winPtr = nextPtr;
	x -= winPtr->changes.x;
	y -= winPtr->changes.y;
    }
    *newX = x;
    *newY = y;
    return (Tk_Window) winPtr;
    return (Tk_Window)winPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateVRootGeometry --
 *
4870
4871
4872
4873
4874
4875
4876
4877

4878
4879
4880
4881
4882
4883
4884
4949
4950
4951
4952
4953
4954
4955

4956
4957
4958
4959
4960
4961
4962
4963







-
+







				 * queried. */
    int *xPtr, int *yPtr,	/* Store x and y offsets of virtual root
				 * here. */
    int *widthPtr,		/* Store dimensions of virtual root here. */
    int *heightPtr)
{
    WmInfo *wmPtr;
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *winPtr = (TkWindow *)tkwin;

    /*
     * Find the top-level window for tkwin, and locate the window manager
     * information for that window.
     */

    while (!(winPtr->flags & TK_TOP_LEVEL)) {
4921
4922
4923
4924
4925
4926
4927
4928

4929
4930
4931
4932
4933
4934
4935
5000
5001
5002
5003
5004
5005
5006

5007
5008
5009
5010
5011
5012
5013
5014







-
+







 */

void
Tk_MoveToplevelWindow(
    Tk_Window tkwin,		/* Window to move. */
    int x, int y)		/* New location for window (within parent). */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *winPtr = (TkWindow *)tkwin;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (!(winPtr->flags & TK_TOP_LEVEL)) {
	Tcl_Panic("Tk_MoveToplevelWindow called with non-toplevel window");
    }
    wmPtr->x = x;
    wmPtr->y = y;
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
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







-
+















-
+







     */

    if (winPtr->window == None ||
	    wmPtr == NULL      ||
	    wmPtr->hints.initial_state == WithdrawnState) {
	return;
    }
    macWindow = TkMacOSXDrawableWindow(winPtr->window);
    macWindow = TkMacOSXGetNSWindowForDrawable(winPtr->window);
    if (macWindow == nil) {
	return;
    }
    if (otherPtr) {
	/*
	 * When otherPtr is non-NULL, if the other window has no drawable or is
	 * withdrawn, do nothing.
	 */

	WmInfo *otherWmPtr = otherPtr->wmInfoPtr;
	if (winPtr->window == None ||
		otherWmPtr == NULL ||
		otherWmPtr->hints.initial_state == WithdrawnState) {
	    return;
	}
	otherMacWindow = TkMacOSXDrawableWindow(otherPtr->window);
	otherMacWindow = TkMacOSXGetNSWindowForDrawable(otherPtr->window);
	if (otherMacWindow == nil) {
	    return;
	}

	/*
	 * If the other window is OK, get its number.
	 */
5113
5114
5115
5116
5117
5118
5119
5120

5121
5122
5123
5124
5125
5126
5127
5192
5193
5194
5195
5196
5197
5198

5199
5200
5201
5202
5203
5204
5205
5206







-
+







	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.
     */
}

/*
 *----------------------------------------------------------------------
 *
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
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







-
+






-
+


-
+


-
+








-
+



-
+









-
+
+














+
-
-
-
+
+
+
-

-
-
-
+
-
-





-
+

-
+
+
+


+
-
+







-
-
-
+
+
+

-
+

+
+
-
+

-
+







    Tk_Uid titleUid)
{
    if (Tk_IsEmbedded(winPtr)) {
	return;
    }

    NSString *title = [[NSString alloc] initWithUTF8String:titleUid];
    [TkMacOSXDrawableWindow(winPtr->window) setTitle:title];
    [TkMacOSXGetNSWindowForDrawable(winPtr->window) setTitle:title];
    [title release];
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetTransientMaster --
 * TkMacOSXGetContainer --
 *
 *	If the passed window has the TRANSIENT_FOR property set this will
 *	return the master window. Otherwise it will return None.
 *	return the container window. Otherwise it will return None.
 *
 * Results:
 *	The master window or None.
 *	The container window or None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tk_Window
TkGetTransientMaster(
TkMacOSXGetContainer(
    TkWindow *winPtr)
{
    if (winPtr->wmInfoPtr != NULL) {
	return (Tk_Window)winPtr->wmInfoPtr->master;
	return (Tk_Window)winPtr->wmInfoPtr->container;
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetXWindow --
 *
 *	Returns the X window Id associated with the given NSWindow*.
 *	Stub function that returns the X window Id associated with the
 *      given NSWindow*.
 *
 * Results:
 *	The window id is returned. None is returned if not a Tk window.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Window
TkMacOSXGetXWindow(
    void *macWinPtr)
{
    Window window = None;
    Tcl_HashEntry *hPtr;

    if (!macWinPtr || !windowHashInit) {
    TKWindow *w = (TKWindow *)macWinPtr;
    if ([w respondsToSelector: @selector (tkWindow)]) {
	window = [w tkWindow];
	return None;
    }
    hPtr = Tcl_FindHashEntry(&windowTable, macWinPtr);
    if (hPtr == NULL) {
	return None;
    return window ? window : None;
    }
    return (Window) Tcl_GetHashValue(hPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetTkWindow --
 * Tk_MacOSXGetTkWindow --
 *
 *	Returns the TkWindow* associated with the given NSWindow*.
 *	Returns the Tk_Window associated with the given NSWindow*.  This
 *      function is a stub, so the NSWindow* parameter must be declared as
 *      void*.
 *
 * Results:
 *	A Tk_Window, or NULL if the NSWindow is not associated with
 *	The TkWindow* returned. NULL is returned if not a Tk window.
 *      any Tk window.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TkWindow*
TkMacOSXGetTkWindow(
    NSWindow *w)
Tk_Window
Tk_MacOSXGetTkWindow(
    void *w)
{
    Window window = TkMacOSXGetXWindow(w);
    Window window = None;
    TkDisplay *dispPtr = TkGetDisplayList();
    if ([(NSWindow *)w respondsToSelector: @selector (tkWindow)]) {
	window = [(TKWindow *)w tkWindow];

    }
    return (window != None ?
	    (TkWindow *)Tk_IdToWindow(dispPtr->display, window) : NULL);
	    Tk_IdToWindow(dispPtr->display, window) : NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXIsWindowZoomed --
 *
5461
5462
5463
5464
5465
5466
5467
5468

5469
5470
5471
5472
5473
5474
5475
5542
5543
5544
5545
5546
5547
5548

5549
5550
5551
5552
5553
5554
5555
5556







-
+







 *----------------------------------------------------------------------
 */

MODULE_SCOPE int
TkMacOSXIsWindowZoomed(
    TkWindow *winPtr)
{
    NSWindow *macWindow = TkMacOSXDrawableWindow(winPtr->window);
    NSWindow *macWindow = TkMacOSXGetNSWindowForDrawable(winPtr->window);
    return [macWindow isZoomed];
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXZoomToplevel --
5616
5617
5618
5619
5620
5621
5622
5623

5624
5625
5626
5627
5628
5629
5630
5697
5698
5699
5700
5701
5702
5703

5704
5705
5706
5707
5708
5709
5710
5711







-
+







	return WmWinAppearance(interp, winPtr, objc, objv);
    case TKMWS_ISDARK:
	if ((objc != 3)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
		TkMacOSXInDarkMode((Tk_Window) winPtr)));
		TkMacOSXInDarkMode((Tk_Window)winPtr)));
	return TCL_OK;
    default:
	return TCL_ERROR;
    }
}

/*
5840
5841
5842
5843
5844
5845
5846
5847








5848
5849
5850

5851
5852
5853
5854
5855
5856


5857
5858
5859
5860
5861
5862
5863
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







-
+
+
+
+
+
+
+
+


-
+





-
+
+







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;
#endif
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
    Tcl_Obj *result = NULL;
    NSString *idString;
    NSWindow *win = TkMacOSXDrawableWindow(winPtr->window);
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(winPtr->window);
    if (win) {
	idString = win.tabbingIdentifier;
	result = Tcl_NewStringObj(idString.UTF8String, [idString length]);
    }
    if (result == NULL) {
	NSLog(@"Failed to read tabbing identifier; try calling update idletasks before getting/setting the tabbing identifier of the window.");
	NSLog(@"Failed to read tabbing identifier; try calling update idletasks"
	      " before getting/setting the tabbing identifier of the window.");
	return TCL_OK;
    }
    Tcl_SetObjResult(interp, result);
    if (objc == 3) {
	return TCL_OK;
    } else if (objc == 4) {
	int len;
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
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







+
+
+
+
+
+
+















-
+







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
    (void) interp;
    (void) winPtr;
    (void) objc;
    (void) objv;
    return TCL_OK;
#endif
#if MAC_OS_X_VERSION_MAX_ALLOWED > 1090
    static const char *const appearanceStrings[] = {
	"aqua", "darkaqua", "auto", NULL
    };
    enum appearances {
	APPEARANCE_AQUA, APPEARANCE_DARKAQUA, APPEARANCE_AUTO
    };
    Tcl_Obj *result = NULL;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
    NSAppearanceName appearance;
#else
    NSString *appearance;
#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 101300

    const char *resultString = "unrecognized";
    NSWindow *win = TkMacOSXDrawableWindow(winPtr->window);
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(winPtr->window);
    if (win) {
	appearance = win.appearance.name;
	if (appearance == nil) {
	    resultString = appearanceStrings[APPEARANCE_AUTO];
	} else if (appearance == NSAppearanceNameAqua) {
	    resultString = appearanceStrings[APPEARANCE_AQUA];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
6008
6009
6010
6011
6012
6013
6014
6015

6016
6017
6018
6019
6020
6021
6022
6104
6105
6106
6107
6108
6109
6110

6111
6112
6113
6114
6115
6116
6117
6118







-
+







TkpMakeMenuWindow(
    Tk_Window tkwin,		/* New window. */
    int transient)		/* 1 means menu is only posted briefly as a
				 * popup or pulldown or cascade. 0 means menu
				 * is always visible, e.g. as a floating
				 * menu. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *winPtr = (TkWindow *)tkwin;

    if (transient) {
	winPtr->wmInfoPtr->macClass = kSimpleWindowClass;
	winPtr->wmInfoPtr->attributes = kWindowNoActivatesAttribute;
    } else {
	winPtr->wmInfoPtr->macClass = kFloatingWindowClass;
	winPtr->wmInfoPtr->attributes = kWindowStandardFloatingAttributes;
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
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







-
+





-
+
















-
-
+
-
-
-
-
-
-







void
TkMacOSXMakeRealWindowExist(
    TkWindow *winPtr)		/* Tk window. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    MacDrawable *macWin;
    WindowClass macClass;
    Bool overrideRedirect = Tk_Attributes((Tk_Window) winPtr)->override_redirect;
    Bool overrideRedirect = Tk_Attributes((Tk_Window)winPtr)->override_redirect;

    if (TkMacOSXHostToplevelExists(winPtr)) {
	return;
    }

    macWin = (MacDrawable *) winPtr->window;
    macWin = (MacDrawable *)winPtr->window;

    /*
     * If this is embedded, make sure its container's toplevel exists, then
     * return...
     */

    if (Tk_IsEmbedded(winPtr)) {
	TkWindow *contWinPtr = TkpGetOtherWindow(winPtr);

	if (contWinPtr != NULL) {
	    TkMacOSXMakeRealWindowExist(
		    contWinPtr->privatePtr->toplevel->winPtr);
	    macWin->flags |= TK_HOST_EXISTS;
	    return;
	}

	if (tkMacOSXEmbedHandler == NULL) {
	    Tcl_Panic("TkMacOSXMakeRealWindowExist could not find container");
	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.
	 */
    }

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







-
+

-
+






+
+
-
+












-
+



















-
+






-
-
+
+







	((attributes & kWindowResizableAttribute) ? NSResizableWindowMask : 0) |
	((attributes & kWindowMetalAttribute) ?
		NSTexturedBackgroundWindowMask : 0) |
	((attributes & kWindowUnifiedTitleAndToolbarAttribute) ?
		NSUnifiedTitleAndToolbarWindowMask : 0) |
	((attributes & kWindowSideTitlebarAttribute) ? 1 << 9 : 0) |
	(attributes >> WM_NSMASK_SHIFT);
    Class winClass = (macClass == kDrawerWindowClass ? [NSDrawerWindow class] :
    Class winClass = (macClass == kDrawerWindowClass ? [TKDrawerWindow class] :
	    (styleMask & (NSUtilityWindowMask|NSDocModalWindowMask|
	    NSNonactivatingPanelMask|NSHUDWindowMask)) ? [NSPanel class] :
	    NSNonactivatingPanelMask|NSHUDWindowMask)) ? [TKPanel class] :
	    [TKWindow class]);
    NSRect structureRect = [winClass frameRectForContentRect:NSZeroRect
	    styleMask:styleMask];
    NSRect contentRect = NSMakeRect(5 - structureRect.origin.x,
	    TkMacOSXZeroScreenHeight() - (TkMacOSXZeroScreenTop() + 5 +
	    structureRect.origin.y + structureRect.size.height + 200), 200, 200);
    if (wmPtr->hints.initial_state == WithdrawnState) {
    }
    NSWindow *window = [[winClass alloc] initWithContentRect:contentRect
    TKWindow *window = [[winClass alloc] initWithContentRect:contentRect
	    styleMask:styleMask backing:NSBackingStoreBuffered defer:YES];
    if (!window) {
    	Tcl_Panic("couldn't allocate new Mac window");
    }
    TKContentView *contentView = [[TKContentView alloc]
				     initWithFrame:NSZeroRect];
    [window setContentView:contentView];
    [contentView release];
    [window setDelegate:NSApp];
    [window setAcceptsMouseMovedEvents:YES];
    [window setReleasedWhenClosed:NO];
    if (styleMask & NSUtilityWindowMask) {
	[(NSPanel*)window setFloatingPanel:YES];
	[(TKPanel*)window setFloatingPanel:YES];
    }
    if ((styleMask & (NSTexturedBackgroundWindowMask|NSHUDWindowMask)) &&
	    !(styleMask & NSDocModalWindowMask)) {
        /*
	 * Workaround for [Bug 2824538]: Textured windows are draggable from
	 *                               opaque content.
	 */
	[window setMovableByWindowBackground:NO];
    }
    [window setDocumentEdited:NO];
    wmPtr->window = window;
    macWin->view = window.contentView;
    TkMacOSXApplyWindowAttributes(winPtr, window);
    NSRect geometry = InitialWindowBounds(winPtr, window);
    geometry.size.width += structureRect.size.width;
    geometry.size.height += structureRect.size.height;
    geometry.origin.y = TkMacOSXZeroScreenHeight() - (geometry.origin.y +
	    geometry.size.height);
    [window setFrame:geometry display:YES];
    TkMacOSXRegisterOffScreenWindow((Window) macWin, window);
    [window setTkWindow: (Window) macWin];

    macWin->flags |= TK_HOST_EXISTS;
    if (overrideRedirect) {
    	XSetWindowAttributes atts;

    	atts.override_redirect = True;
    	Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect, &atts);
    	ApplyMasterOverrideChanges(winPtr, NULL);
    	Tk_ChangeWindowAttributes((Tk_Window)winPtr, CWOverrideRedirect, &atts);
    	ApplyContainerOverrideChanges(winPtr, NULL);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpRedrawWidget --
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
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







-
+







-
+

-
+





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







 *      The widget's bounding rectangle is marked as dirty.
 *
 *----------------------------------------------------------------------
 */

void
TkpRedrawWidget(Tk_Window tkwin) {
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *winPtr = (TkWindow *)tkwin;
    NSWindow *w;
    Rect tkBounds;
    NSRect bounds;

    if ([NSApp isDrawing]) {
	return;
    }
    w = TkMacOSXDrawableWindow(winPtr->window);
    w = TkMacOSXGetNSWindowForDrawable(winPtr->window);
    if (w) {
	NSView *view = [w contentView];
	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 setNeedsDisplayInRect:bounds];
	[view setTkNeedsDisplay:YES];
    }
}

	[view setTkDirtyRect:bounds];
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXRegisterOffScreenWindow --
 *
 *	This function adds the passed in Off Screen Port to the hash table that
 *	maps Mac windows to root X windows.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	An entry is added to the windowTable hash table.
 *
 *----------------------------------------------------------------------
 */

    }
void
TkMacOSXRegisterOffScreenWindow(
    Window window,		/* Window structure. */
    void *portPtr)		/* Pointer to a Mac Window. */
{
    Tcl_HashEntry *valueHashPtr;
    int isNew;

}
    if (!windowHashInit) {
	Tcl_InitHashTable(&windowTable, TCL_ONE_WORD_KEYS);
	windowHashInit = true;
    }

    valueHashPtr = Tcl_CreateHashEntry(&windowTable, (char *) portPtr, &isNew);
    if (!isNew) {
	Tcl_Panic("Same macintosh window allocated twice!");
    }
    Tcl_SetHashValue(valueHashPtr, window);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXUnregisterMacWindow --
 *
 *	Given a macintosh port window, this function removes the association
 *	between this window and the root X window that Tk cares about.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	An entry is removed from the windowTable hash table.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXUnregisterMacWindow(
    void *macWinPtr)	/* Reference to a Mac Window */
{
    Tcl_HashEntry *entryPtr;

    if (!windowHashInit) {
	Tcl_Panic("TkMacOSXUnregisterMacWindow: unmapping before inited");
    }
    entryPtr = Tcl_FindHashEntry(&windowTable, macWinPtr);
    if (!entryPtr) {
	TkMacOSXDbgMsg("Failed to find window %p", macWinPtr);
    } else {
	Tcl_DeleteHashEntry(entryPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXSetScrollbarGrow --
 *
 *	Sets a flag for a toplevel window indicating that the passed Tk
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
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







-
+


-
+

+









-
+

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







    NSWindow *macWin;

    wmPtr->hints.initial_state = state;
    if (wmPtr->flags & WM_NEVER_MAPPED) {
	return;
    }

    macWin = TkMacOSXDrawableWindow(winPtr->window);
    macWin = TkMacOSXGetNSWindowForDrawable(winPtr->window);

    if (state == WithdrawnState) {
	Tk_UnmapWindow((Tk_Window) winPtr);
	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);
	Tk_UnmapWindow((Tk_Window)winPtr);
    } else if (state == NormalState || state == ZoomState) {
	Tk_MapWindow((Tk_Window) winPtr);
	Tk_MapWindow((Tk_Window)winPtr);
	if (macWin && ([macWin styleMask] & NSMiniaturizableWindowMask) &&
		[macWin isMiniaturized]) {
	    [macWin deminiaturize:NSApp];
	}
	[macWin deminiaturize:NSApp];
	[macWin orderFront:NSApp];
	TkMacOSXZoomToplevel(macWin, state == NormalState ? inZoomIn : inZoomOut);
    }
	TkMacOSXZoomToplevel(macWin, state == NormalState ? inZoomIn :
		inZoomOut);
    }
    /*
     * Make sure windows are updated after the state change.
     */

    while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)){}
}

/*
 *----------------------------------------------------------------------
 *
 * TkpIsWindowFloating --
 *
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
6476
6477
6478
6479
6480
6481
6482























6483
6484
6485
6486
6487
6488
6489







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








int
TkpIsWindowFloating(
    void *wRef)
{
    return [(NSWindow *)wRef level] == kCGFloatingWindowLevel;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXWindowClass --
 *
 *	Returns OS X window class of window
 *
 * Results:
 *	1 or 0 depending on window's floating attribute.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE WindowClass
TkMacOSXWindowClass(
    TkWindow *winPtr)
{
    return winPtr->wmInfoPtr->macClass;
}

/*
 *--------------------------------------------------------------
 *
 * TkMacOSXWindowOffset --
 *
 *	Determines the x and y offset from the orgin of the toplevel window
6598
6599
6600
6601
6602
6603
6604
6605

6606
6607
6608
6609
6610
6611
6612
6601
6602
6603
6604
6605
6606
6607

6608
6609
6610
6611
6612
6613
6614
6615







-
+







				 * application. */
{
    if (winPtr->atts.override_redirect) {
	return 0;
    }

    if (Tk_IsTopLevel(winPtr) && !Tk_IsEmbedded(winPtr)) {
    	NSWindow *win = TkMacOSXDrawableWindow(winPtr->window);
    	NSWindow *win = TkMacOSXGetNSWindowForDrawable(winPtr->window);

    	TkWmRestackToplevel(winPtr, Above, NULL);
    	if (force) {
    	    [NSApp activateIgnoringOtherApps:YES];
    	}
	if (win && [win canBecomeKeyWindow]) {
	    [win makeKeyAndOrderFront:NSApp];
6653
6654
6655
6656
6657
6658
6659
6660

6661
6662
6663
6664
6665
6666
6667
6656
6657
6658
6659
6660
6661
6662

6663
6664
6665
6666
6667
6668
6669
6670







-
+







    TkWindow *childPtr;
    Tcl_HashEntry *hPtr;
    int newEntry;

    if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr) && !Tk_IsEmbedded(winPtr)
	    && (winPtr->display == display)) {
	hPtr = Tcl_CreateHashEntry(table,
		(char*) TkMacOSXDrawableWindow(winPtr->window), &newEntry);
		(void *)TkMacOSXGetNSWindowForDrawable(winPtr->window), &newEntry);
	Tcl_SetHashValue(hPtr, winPtr);
    }

    for (childPtr = winPtr->childList; childPtr != NULL;
	    childPtr = childPtr->nextPtr) {
	WmStackorderToplevelWrapperMap(childPtr, display, table);
    }
6732
6733
6734
6735
6736
6737
6738
6739
6740


6741
6742
6743
6744
6745
6746
6747
6735
6736
6737
6738
6739
6740
6741


6742
6743
6744
6745
6746
6747
6748
6749
6750







-
-
+
+







TkMacOSXApplyWindowAttributes(
    TkWindow *winPtr,
    NSWindow *macWindow)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    ApplyWindowAttributeFlagChanges(winPtr, macWindow, 0, 0, 0, 1);
    if (wmPtr->master != NULL || winPtr->atts.override_redirect) {
	ApplyMasterOverrideChanges(winPtr, macWindow);
    if (wmPtr->container != NULL || winPtr->atts.override_redirect) {
	ApplyContainerOverrideChanges(winPtr, macWindow);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ApplyWindowAttributeFlagChanges --
6773
6774
6775
6776
6777
6778
6779
6780

6781
6782
6783
6784
6785
6786
6787
6788

6789
6790
6791
6792
6793
6794
6795
6776
6777
6778
6779
6780
6781
6782

6783
6784
6785
6786
6787
6788
6789
6790

6791
6792
6793
6794
6795
6796
6797
6798







-
+







-
+








    if (changedAttributes || wmPtr->flags != oldFlags || initial) {
	if (!macWindow) {
	    if (winPtr->window == None) {
		if (!create) {
		    return;
		}
		Tk_MakeWindowExist((Tk_Window) winPtr);
		Tk_MakeWindowExist((Tk_Window)winPtr);
	    }
	    if (!TkMacOSXHostToplevelExists(winPtr)) {
		if (!create) {
		    return;
		}
		TkMacOSXMakeRealWindowExist(winPtr);
	    }
	    macWindow = TkMacOSXDrawableWindow(winPtr->window);
	    macWindow = TkMacOSXGetNSWindowForDrawable(winPtr->window);
	}
	if ((changedAttributes & kWindowCloseBoxAttribute) || initial) {
	    [[macWindow standardWindowButton:NSWindowCloseButton]
		    setEnabled:!!(newAttributes & kWindowCloseBoxAttribute)];
	}
	if ((changedAttributes & kWindowCollapseBoxAttribute) || initial) {
	    [[macWindow standardWindowButton:NSWindowMiniaturizeButton]
6858
6859
6860
6861
6862
6863
6864
6865

6866
6867
6868
6869
6870
6871
6872
6873

6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887

6888


6889
6890
6891
6892
6893
6894
6895
6861
6862
6863
6864
6865
6866
6867

6868
6869
6870
6871
6872
6873
6874
6875

6876
6877
6878
6879
6880

6881
6882
6883
6884
6885
6886
6887
6888
6889
6890

6891
6892
6893
6894
6895
6896
6897
6898
6899







-
+







-
+




-









+
-
+
+







	    /*
	     * This behavior, which makes the green button expand a window to
	     * full screen, was included in the default as of OSX 10.13.  For
	     * uniformity we use the new default in all versions of the OS
	     * after 10.10.
	     */

#if !(MAC_OS_X_VERSION_MAX_ALLOWED < 101000)
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101100
	    if (!(macWindow.styleMask & NSUtilityWindowMask)) {
		/*
		 * Exclude overrideredirect, transient, and "help"-styled
		 * windows from moving into their own fullscreen space.
		 */

		if ((winPtr->atts.override_redirect) ||
			(wmPtr->master != NULL) ||
			(wmPtr->container != NULL) ||
			(winPtr->wmInfoPtr->macClass == kHelpWindowClass)) {
		    b |= (NSWindowCollectionBehaviorCanJoinAllSpaces |
			    NSWindowCollectionBehaviorFullScreenAuxiliary);
		} else {
		    NSSize screenSize = [[macWindow screen] frame].size;
		    b |= NSWindowCollectionBehaviorFullScreenPrimary;

		    /*
		     * The default max size has height less than the screen
		     * height. This causes the window manager to refuse to
		     * allow the window to be resized when it is a split
		     * window. To work around this we make the max size equal
		     * to the screen size.  (For 10.11 and up, only)
		     */

		    if ([NSApp macOSVersion] > 101000) {
		    if ([NSApp macOSVersion] >= 101100) {
			NSSize screenSize = [[macWindow screen] frame].size;
			[macWindow setMaxFullScreenContentSize:screenSize];
		    }
		}
	    }
#endif

	    if (newAttributes & tkCanJoinAllSpacesAttribute) {
6903
6904
6905
6906
6907
6908
6909
6910

6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931

6932
6933

6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945

6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958

6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979

6980
6981
6982
6983
6984
6985
6986
6907
6908
6909
6910
6911
6912
6913

6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934

6935
6936

6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948

6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961

6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982

6983
6984
6985
6986
6987
6988
6989
6990







-
+




















-
+

-
+











-
+












-
+




















-
+







		b |= NSWindowCollectionBehaviorParticipatesInCycle;
	    }
	    [macWindow setCollectionBehavior:b];
	}
	if ((wmPtr->flags & WM_TOPMOST) != (oldFlags & WM_TOPMOST)) {
	    [macWindow setLevel:(wmPtr->flags & WM_TOPMOST) ?
		    kCGUtilityWindowLevel : ([macWindow isKindOfClass:
		    [NSPanel class]] && [macWindow isFloatingPanel] ?
		    [TKPanel class]] && [macWindow isFloatingPanel] ?
		    kCGFloatingWindowLevel : kCGNormalWindowLevel)];
	}

	/*
	 * The change of window class/attributes might have changed the window
	 * frame geometry:
	 */

	NSRect structureRect = [macWindow frameRectForContentRect:NSZeroRect];

	wmPtr->xInParent = -structureRect.origin.x;
	wmPtr->yInParent = structureRect.origin.y + structureRect.size.height;
	wmPtr->parentWidth = winPtr->changes.width + structureRect.size.width;
	wmPtr->parentHeight = winPtr->changes.height + structureRect.size.height;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ApplyMasterOverrideChanges --
 * ApplyContainerOverrideChanges --
 *
 *	This procedure applies changes to override_redirect or master.
 *	This procedure applies changes to override_redirect or container.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
ApplyMasterOverrideChanges(
ApplyContainerOverrideChanges(
    TkWindow *winPtr,
    NSWindow *macWindow)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    UInt64 oldAttributes = wmPtr->attributes;
    int oldFlags = wmPtr->flags;
    unsigned long styleMask;
    NSRect structureRect;
    NSWindow *parentWindow;

    if (!macWindow && winPtr->window != None &&
	    TkMacOSXHostToplevelExists(winPtr)) {
	macWindow = TkMacOSXDrawableWindow(winPtr->window);
	macWindow = TkMacOSXGetNSWindowForDrawable(winPtr->window);
    }
    styleMask = [macWindow styleMask];

    /*
     * FIX: We need an UpdateWrapper equivalent to make this 100% correct
     */

    if (winPtr->atts.override_redirect) {
	if (wmPtr->macClass == kDocumentWindowClass) {
	    wmPtr->macClass = kSimpleWindowClass;
	    wmPtr->attributes = macClassAttrs[kSimpleWindowClass].defaultAttrs;
	}
	wmPtr->attributes |= kWindowNoActivatesAttribute;
	if ([NSApp macOSVersion] == 100600) {
	    styleMask = 0;
	} else {
	    styleMask &= ~NSTitledWindowMask;
	}
    } else {
	if (wmPtr->macClass == kSimpleWindowClass &&
		oldAttributes == kWindowNoActivatesAttribute) {
	    (oldAttributes & kWindowNoActivatesAttribute)) {
	    wmPtr->macClass = kDocumentWindowClass;
	    wmPtr->attributes =
		    macClassAttrs[kDocumentWindowClass].defaultAttrs;
	}
	wmPtr->attributes &= ~kWindowNoActivatesAttribute;
	if ([NSApp macOSVersion] == 100600) {
	    styleMask = NSTitledWindowMask         |
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
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







-
+

-
+















-
-
+
+

-
-
-
-
+
+
+
+



-
-
-
-
-
+
+
+
+
+


-
+







-
+


-
-
-
+
+
+







	wmPtr->yInParent = structureRect.origin.y + structureRect.size.height;
	wmPtr->parentWidth = winPtr->changes.width + structureRect.size.width;
	wmPtr->parentHeight = winPtr->changes.height + structureRect.size.height;
	if (winPtr->atts.override_redirect) {
	    [macWindow setExcludedFromWindowsMenu:YES];
	    [macWindow setStyleMask:styleMask];
	    if (wmPtr->hints.initial_state == NormalState) {
		[macWindow orderFront:nil];
		[macWindow orderFront:NSApp];
	    }
	    if (wmPtr->master != NULL) {
	    if (wmPtr->container != NULL) {
		wmPtr->flags |= WM_TOPMOST;
	    } else {
		wmPtr->flags &= ~WM_TOPMOST;
	    }
	} else {
	    const char *title = winPtr->wmInfoPtr->titleUid;

	    if (!title) {
		title = winPtr->nameUid;
	    }
	    [macWindow setStyleMask:styleMask];
	    [macWindow setTitle:[NSString stringWithUTF8String:title]];
	    [macWindow setExcludedFromWindowsMenu:NO];
	    wmPtr->flags &= ~WM_TOPMOST;
	}
	if (wmPtr->master != None) {
	    TkWindow *masterWinPtr = (TkWindow *) wmPtr->master;
	if (wmPtr->container != None) {
	    TkWindow *containerWinPtr = (TkWindow *)wmPtr->container;

	    if (masterWinPtr && (masterWinPtr->window != None)
		    && TkMacOSXHostToplevelExists(masterWinPtr)) {
		NSWindow *masterMacWin = TkMacOSXDrawableWindow(
			masterWinPtr->window);
	    if (containerWinPtr && (containerWinPtr->window != None)
		    && TkMacOSXHostToplevelExists(containerWinPtr)) {
		NSWindow *containerMacWin = TkMacOSXGetNSWindowForDrawable(
			containerWinPtr->window);

		/*
		 * Try to add the transient window as a child window of the
		 * master. A child NSWindow retains its relative position with
		 * respect to the parent when the parent is moved.  This is
		 * pointless if the parent is offscreen, and adding a child to
		 * an offscreen window causes the parent to be displayed as a
		 * zombie.  So we only do this if the parent is visible.
		 * container. A child NSWindow retains its relative position
		 * with respect to the parent when the parent is moved.  This
		 * is pointless if the parent is offscreen, and adding a child
		 * to an offscreen window causes the parent to be displayed as
		 * a zombie.  So we only do this if the parent is visible.
		 */

		if (masterMacWin && [masterMacWin isVisible]
		if (containerMacWin && [containerMacWin isVisible]
			&& (winPtr->flags & TK_MAPPED)) {
		    /*
		     * If the transient is already a child of some other window,
		     * remove it.
		     */

		    parentWindow = [macWindow parentWindow];
		    if (parentWindow && parentWindow != masterMacWin) {
		    if (parentWindow && parentWindow != containerMacWin) {
			[parentWindow removeChildWindow:macWindow];
		    }

		    [masterMacWin addChildWindow:macWindow
					 ordered:NSWindowAbove];
		    [macWindow orderFront:NSApp];
		    [containerMacWin addChildWindow:macWindow
					    ordered:NSWindowAbove];
		}
	    }
	} else {
	    parentWindow = [macWindow parentWindow];
	    if (parentWindow) {
		[parentWindow removeChildWindow:macWindow];
	    }
7251
7252
7253
7254
7255
7256
7257
7258

7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275

7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7255
7256
7257
7258
7259
7260
7261

7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278

7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290







-
+
















-
+












    /*
     * Remove the OS specific window. It will get rebuilt when the window gets
     * Mapped.
     */

    if (winPtr->window != None) {
	MacDrawable *macWin = (MacDrawable *) winPtr->window;
	MacDrawable *macWin = (MacDrawable *)winPtr->window;

	macWin->toplevel->referenceCount--;
	macWin->toplevel = parentWin->toplevel;
	macWin->toplevel->referenceCount++;
	winPtr->flags &= ~TK_MAPPED;
#ifdef TK_REBUILD_TOPLEVEL
	winPtr->flags |= TK_REBUILD_TOPLEVEL;
#endif
    }

    /*
     * Repeat for all the children.
     */

    for (childPtr = winPtr->childList; childPtr != NULL;
	    childPtr = childPtr->nextPtr) {
	RemapWindows(childPtr, (MacDrawable *) winPtr->window);
	RemapWindows(childPtr, (MacDrawable *)winPtr->window);
    }
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXWm.h.

1
2
3
4
5
6
7


8
9
10
11
12
13
14
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 <[email protected]>
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2006-2009 Daniel A. Steffen <[email protected]>
 *
 * 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
33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69


70
71
72
73
74
75
76
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56
57
58
59
60
61
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;

/* The following data structure is used in the TkWmInfo to maintain a list of all of the
 * transient windows belonging to a given master.
 * transient windows belonging to a given container.
 */

typedef struct Transient {
    TkWindow *winPtr;
    int flags;
    struct Transient *nextPtr;
} Transient;

#define WITHDRAWN_BY_MASTER 0x1
#define WITHDRAWN_BY_CONTAINER 0x1

/*
 * A data structure of the following type holds window-manager-related
 * information for each top-level window in an application.
 */

typedef struct TkWmInfo {
    TkWindow *winPtr;		/* Pointer to main Tk information for this
				 * window. */
    Window reparent;		/* If the window has been reparented, this
				 * gives the ID of the ancestor of the window
				 * that is a child of the root window (may not
				 * be window's immediate parent). If the window
				 * isn't reparented, this has the value
				 * None. */
    Tk_Uid titleUid;		/* Title to display in window caption. If NULL,
				 * use name of widget. */
    char *iconName;		/* Name to display in icon. */
    Tk_Window master;		/* Master window for TRANSIENT_FOR property, or
				 * None. */
    Tk_Window container;		/* Container window for TRANSIENT_FOR property,
				 * or None. */
    XWMHints hints;		/* Various pieces of information for window
				 * manager. */
    char *leaderName;		/* Path name of leader of window group
				 * (corresponds to hints.window_group).
				 * Malloc-ed. Note: this field doesn't get
				 * updated if leader is destroyed. */
    Tk_Window icon;		/* Window to use as icon for this window, or

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. ([email protected])
 *
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
 * Copyright 2008-2009, Apple Inc.
 * Copyright (c) 2008-2009 Daniel A. Steffen <[email protected]>
 * Copyright © 1995-1996 Sun Microsystems, Inc.
 * Copyright © 2008-2009 Apple Inc.
 * Copyright © 2008-2009 Daniel A. Steffen <[email protected]>
 *
 * 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
1
2
3
4
5
6
7
8




9
10
11
12
13
14
15
16
17
18
19








-
-
-
-
+
+
+
+







/*
 * 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 <[email protected]>
 * Copyright 2014 Marc Culler.
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009, Apple Inc.
 * Copyright © 2005-2009 Daniel A. Steffen <[email protected]>
 * Copyright © 2014 Marc Culler.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXInt.h"
252
253
254
255
256
257
258
259
260


261
262
263
264
265
266
267
252
253
254
255
256
257
258


259
260
261
262
263
264
265
266
267







-
-
+
+







    display->display_name   = (char *) macScreenName;

    /*
     * These screen bits never change
     */
    screen->root	= ROOT_ID;
    screen->display	= display;
    screen->black_pixel = 0x00000000 | PIXEL_MAGIC << 24;
    screen->white_pixel = 0x00FFFFFF | PIXEL_MAGIC << 24;
    screen->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;
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







-







    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.
484
485
486
487
488
489
490
491

492
493
494
495
496
497
498
499
500
501
502
503

504
505
506
507
508
509
510
483
484
485
486
487
488
489

490
491
492
493
494
495
496
497
498
499
500
501

502
503
504
505
506
507
508
509







-
+











-
+







    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;
    TkWindow *winPtr = ((MacDrawable *)d)->winPtr;

    display->request++;
    *root_return = ROOT_ID;
    if (winPtr) {
	*x_return = Tk_X(winPtr);
	*y_return = Tk_Y(winPtr);
	*width_return = Tk_Width(winPtr);
	*height_return = Tk_Height(winPtr);
	*border_width_return = winPtr->changes.border_width;
	*depth_return = Tk_Depth(winPtr);
    } else {
	CGSize size = ((MacDrawable *) d)->size;
	CGSize size = ((MacDrawable *)d)->size;
	*x_return = 0;
	*y_return =  0;
	*width_return = size.width;
	*height_return = size.height;
	*border_width_return = 0;
	*depth_return = 32;
    }
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
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







-
+
-








-
+

-
+


-
+

-
-
-
-
+
+
+
+

-
-
+
+


-
-







     * However, there is no real way to do this on a Mac. Let me know if there
     * is!
     */

    display->request++;
    return Success;
}


#if 0
int
XSetClipRectangles(
    Display *d,
    GC gc,
    int clip_x_origin,
    int clip_y_origin,
    XRectangle* rectangles,
    int n,
    int ordering)
    TCL_UNUSED(int))
{
    Region clipRgn = XCreateRegion();
    TkRegion clipRgn = TkCreateRegion();

    while (n--) {
	XRectangle rect = *rectangles;
    	XRectangle rect = *rectangles;

	rect.x += clip_x_origin;
	rect.y += clip_y_origin;
	XUnionRectWithRegion(&rect, clipRgn, clipRgn);
	rectangles++;
    	rect.x += clip_x_origin;
    	rect.y += clip_y_origin;
    	TkUnionRectWithRegion(&rect, clipRgn, clipRgn);
    	rectangles++;
    }
    XSetRegion(d, gc, clipRgn);
    XDestroyRegion(clipRgn);
    TkSetRegion(d, gc, clipRgn);
    TkDestroyRegion(clipRgn);
    return 1;
}
#endif

/*
 *----------------------------------------------------------------------
 *
 * TkGetServerInfo --
 *
 *	Given a window, this procedure returns information about the window
 *	server for that window. This procedure provides the guts of the "winfo
1080
1081
1082
1083
1084
1085
1086
1087

1088
1089
1090
1091
1092
1093
1094
1076
1077
1078
1079
1080
1081
1082

1083
1084
1085
1086
1087
1088
1089
1090







-
+







}

XAfterFunction
XSynchronize(
    Display *display,
    TCL_UNUSED(Bool))
{
	display->request++;
    display->request++;
    return NULL;
}

int
XUngrabServer(
    TCL_UNUSED(Display *))
{
1186
1187
1188
1189
1190
1191
1192
1193

1194
1195
1196
1197
1198
1199
1200
1182
1183
1184
1185
1186
1187
1188

1189
1190
1191
1192
1193
1194
1195
1196







-
+







    io_registry_entry_t regEntry;
    CFMutableDictionaryRef props = NULL;
    CFTypeRef timeObj;
    long ret = -1l;
    uint64_t time;
    IOReturn result;

    regEntry = IOServiceGetMatchingService(kIOMasterPortDefault,
    regEntry = IOServiceGetMatchingService(0,
	    IOServiceMatching("IOHIDSystem"));

    if (regEntry == 0) {
	return -1l;
    }

    result = IORegistryEntryCreateCFProperties(regEntry, &props,

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 <[email protected]>
 * 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 <[email protected]>
 * 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
27
28
29
30
31
32
33

34
35
36
37
38
39
40

41
42
43
44
45
46
47
48







-







-
+







 *
 *      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, 1, &dc)) {return;}
	if (!TkMacOSXSetupDrawingContext((d), NULL, &dc)) {return;}
#define END_DRAWING \
    TkMacOSXRestoreDrawingContext(&dc);}

#define HIOrientation kHIThemeOrientationNormal
#define NoThemeMetric 0xFFFFFFFF

#ifdef __LP64__
149
150
151
152
153
154
155
156

157
158
159
160
161
162
163
148
149
150
151
152
153
154

155
156
157
158
159
160
161
162







-
+







 *    to a native Rect relative to the containing port.
 */

static inline CGRect BoxToRect(
    Drawable d,
    Ttk_Box b)
{
    MacDrawable *md = (MacDrawable *) d;
    MacDrawable *md = (MacDrawable *)d;
    CGRect rect;

    rect.origin.y       = b.y + md->yOff;
    rect.origin.x       = b.x + md->xOff;
    rect.size.height    = b.height;
    rect.size.width     = b.width;

228
229
230
231
232
233
234
235

236
237
238
239


240
241
242
243
244
245
246
247
248
249





250
251
252
253

254
255
256
257
258
259


260
261
262
263


264
265
266

267
268

269
270

271
272
273
274
275
276
277
278
279
280

281
282
283
284
285
286
287
227
228
229
230
231
232
233

234
235
236


237
238
239
240
241
242
243





244
245
246
247
248
249
250
251

252
253
254
255
256


257
258

259


260
261
262
263

264
265

266
267

268
269
270
271
272
273
274
275
276
277

278
279
280
281
282
283
284
285







-
+


-
-
+
+





-
-
-
-
-
+
+
+
+
+



-
+




-
-
+
+
-

-
-
+
+


-
+

-
+

-
+









-
+







 * 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 CGFloat windowBackground[4] = {
static const CGFloat WINDOWBACKGROUND[4] = {
    235.0 / 255, 235.0 / 255, 235.0 / 255, 1.0
};
static CGFloat whiteRGBA[4] = {1.0, 1.0, 1.0, 1.0};
static CGFloat blackRGBA[4] = {0.0, 0.0, 0.0, 1.0};
static const CGFloat WHITERGBA[4] = {1.0, 1.0, 1.0, 1.0};
static const CGFloat BLACKRGBA[4] = {0.0, 0.0, 0.0, 1.0};

/*----------------------------------------------------------------------
 * GetBackgroundColor --
 *
 *      Fills the array rgba with the color coordinates for a background color.
 *      Start with the background color of a window's geometry master, or the
 *      standard ttk window background if there is no master. If the contrast
 *      parameter is nonzero, modify this color to be darker, for the aqua
 *      appearance, or lighter for the DarkAqua appearance.  This is primarily
 *      used by the Fill and Background elements.
 *      Start with the background color of a window's geometry container, or
 *      the standard ttk window background if there is no container. If the
 *      contrast parameter is nonzero, modify this color to be darker, for the
 *      aqua appearance, or lighter for the DarkAqua appearance.  This is
 *      primarily used by the Fill and Background elements.
 */

static void GetBackgroundColor(
    CGContextRef context,
    TCL_UNUSED(CGContextRef),
    Tk_Window tkwin,
    int contrast,
    CGFloat *rgba)
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *masterPtr = (TkWindow *) TkGetGeomMaster(tkwin);
    TkWindow *winPtr = (TkWindow *)tkwin;
    TkWindow *containerPtr = (TkWindow *)TkGetContainer(tkwin);
    (void)context;

    while (masterPtr && masterPtr->privatePtr) {
	if (masterPtr->privatePtr->flags & TTK_HAS_CONTRASTING_BG) {
    while (containerPtr && containerPtr->privatePtr) {
	if (containerPtr->privatePtr->flags & TTK_HAS_CONTRASTING_BG) {
	    break;
	}
	masterPtr = (TkWindow *) TkGetGeomMaster(masterPtr);
	containerPtr = (TkWindow *)TkGetContainer(containerPtr);
    }
    if (masterPtr && masterPtr->privatePtr) {
    if (containerPtr && containerPtr->privatePtr) {
	for (int i = 0; i < 4; i++) {
	    rgba[i] = masterPtr->privatePtr->fillRGBA[i];
	    rgba[i] = containerPtr->privatePtr->fillRGBA[i];
	}
    } else {
	if ([NSApp macOSVersion] > 101300) {
	    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
	    NSColor *windowColor = [[NSColor windowBackgroundColor]
		colorUsingColorSpace: deviceRGB];
	    [windowColor getComponents: rgba];
	} else {
	    for (int i = 0; i < 4; i++) {
		rgba[i] = windowBackground[i];
		rgba[i] = WINDOWBACKGROUND[i];
	    }
	}
    }
    if (contrast) {
	int isDark = (rgba[0] + rgba[1] + rgba[2] < 1.5);

	if (isDark) {
300
301
302
303
304
305
306
307

308
309


310
311
312
313
314
315
316
317

318
319
320
321
322
323
324
298
299
300
301
302
303
304

305
306

307
308
309
310
311
312
313
314
315

316
317
318
319
320
321
322
323







-
+

-
+
+







-
+







            }
        }
    }
}


/*----------------------------------------------------------------------
 * +++ Single Arrow Buttons --
 * +++ Single Arrow Images --
 *
 * Used in ListHeaders and Comboboxes.
 * Used in ListHeaders and Comboboxes as well as disclosure triangles in
 * macOS 11.
 */

static void DrawDownArrow(
    CGContextRef context,
    CGRect bounds,
    CGFloat inset,
    CGFloat size,
    CGFloat *rgba)
    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);
332
333
334
335
336
337
338
339

340
341
342
343
344
345
346
347
348
349
350
351
352
353
354










































355
356
357
358
359
360
361
362
363
364
365
366
367

368
369
370
371
372
373
374
331
332
333
334
335
336
337

338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407

408
409
410
411
412
413
414
415







-
+















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












-
+







}

static void DrawUpArrow(
    CGContextRef context,
    CGRect bounds,
    CGFloat inset,
    CGFloat size,
    CGFloat *rgba)
    const CGFloat *rgba)
{
    CGFloat x, y;

    CGContextSetRGBStrokeColor(context, rgba[0], rgba[1], rgba[2], rgba[3]);
    CGContextSetLineWidth(context, 1.5);
    x = bounds.origin.x + inset;
    y = bounds.origin.y + trunc(bounds.size.height / 2);
    CGContextBeginPath(context);
    CGPoint arrow[3] = {
	{x, y + size / 4}, {x + size / 2, y - size / 4},
	{x + size, y + size / 4}
    };
    CGContextAddLines(context, arrow, 3);
    CGContextStrokePath(context);
}

static void DrawClosedDisclosure(
    CGContextRef context,
    CGRect bounds,
    CGFloat inset,
    CGFloat size,
    CGFloat *rgba)
{
    CGFloat x, y;

    CGContextSetRGBStrokeColor(context, rgba[0], rgba[1], rgba[2], rgba[3]);
    CGContextSetLineWidth(context, 1.5);
    x = bounds.origin.x + inset;
    y = bounds.origin.y + trunc(bounds.size.height / 2);
    CGContextBeginPath(context);
    CGPoint arrow[3] = {
	{x, y - size / 4 - 1}, {x + size / 2, y}, {x, y + size / 4 + 1}
    };
    CGContextAddLines(context, arrow, 3);
    CGContextStrokePath(context);
}

static void DrawOpenDisclosure(
    CGContextRef context,
    CGRect bounds,
    CGFloat inset,
    CGFloat size,
    CGFloat *rgba)
{
    CGFloat x, y;

    CGContextSetRGBStrokeColor(context, rgba[0], rgba[1], rgba[2], rgba[3]);
    CGContextSetLineWidth(context, 1.5);
    x = bounds.origin.x + inset;
    y = bounds.origin.y + trunc(bounds.size.height / 2);
    CGContextBeginPath(context);
    CGPoint arrow[3] = {
	{x, y - size / 4}, {x + size / 2, y + size / 2}, {x + size, y - size / 4}
    };
    CGContextAddLines(context, arrow, 3);
    CGContextStrokePath(context);
}

/*----------------------------------------------------------------------
 * +++ Double Arrow Buttons --
 *
 * Used in MenuButtons and SpinButtons.
 */

static void DrawUpDownArrows(
    CGContextRef context,
    CGRect bounds,
    CGFloat inset,
    CGFloat size,
    CGFloat *rgba)
    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);
498
499
500
501
502
503
504

505



506

507
508
509
510
511
512
513
514
515
539
540
541
542
543
544
545
546
547
548
549
550

551
552

553
554
555
556
557
558
559







+

+
+
+
-
+

-







static void SolidFillRoundedRectangle(
    CGContextRef context,
    CGRect bounds,
    CGFloat radius,
    NSColor *color)
{
    CGPathRef path;

    CHECK_RADIUS(radius, bounds)
    path = CGPathCreateWithRoundedRect(bounds, radius, radius, NULL);
    if (!path) {
	return;

    }
    CGContextSetFillColorWithColor(context, CGCOLOR(color));
    path = CGPathCreateWithRoundedRect(bounds, radius, radius, NULL);
    CGContextBeginPath(context);
    CGContextAddPath(context, path);
    CGContextFillPath(context);
    CFRelease(path);
}

/*----------------------------------------------------------------------
544
545
546
547
548
549
550
551

552
553
554
555
556
557
558
588
589
590
591
592
593
594

595
596
597
598
599
600
601
602







-
+








    /*
     * Apple changes the background of a list header when the window is not
     * active.  But Ttk does not indicate that in the state of a TreeHeader.
     * So we have to query the Apple window manager.
     */

    NSWindow *win = TkMacOSXDrawableWindow(Tk_WindowId(tkwin));
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(Tk_WindowId(tkwin));
    CGFloat *bgRGBA = [win isKeyWindow] ? activeBgRGBA : inactiveBgRGBA;
    CGFloat x = bounds.origin.x, y = bounds.origin.y;
    CGFloat w = bounds.size.width, h = bounds.size.height;
    CGPoint top[2] = {{x, y + 1}, {x + w, y + 1}};
    CGPoint bottom[2] = {{x, y + h}, {x + w, y + h}};
    CGPoint separator[2] = {{x + w - 1, y + 3}, {x + w - 1, y + h - 3}};

584
585
586
587
588
589
590
591

592
593

594
595
596
597
598
599
600
628
629
630
631
632
633
634

635
636

637
638
639
640
641
642
643
644







-
+

-
+







    CGContextRestoreGState(context);

    if (state & TTK_TREEVIEW_STATE_SORTARROW) {
	CGRect arrowBounds = bounds;
	arrowBounds.origin.x = bounds.origin.x + bounds.size.width - 16;
	arrowBounds.size.width = 16;
	if (state & TTK_STATE_ALTERNATE) {
	    DrawUpArrow(context, arrowBounds, 3, 8, blackRGBA);
	    DrawUpArrow(context, arrowBounds, 3, 8, BLACKRGBA);
	} else if (state & TTK_STATE_SELECTED) {
	    DrawDownArrow(context, arrowBounds, 3, 8, blackRGBA);
	    DrawDownArrow(context, arrowBounds, 3, 8, BLACKRGBA);
	}
    }
}

/*----------------------------------------------------------------------
 * +++ Drawing procedures for widgets in Apple's "Dark Mode" (10.14 and up).
 *
708
709
710
711
712
713
714
715

716
717

718
719
720
721
722
723
724
752
753
754
755
756
757
758

759
760

761
762
763
764
765
766
767
768







-
+

-
+








	if (!(state & TTK_STATE_BACKGROUND) &&
	    !(state & TTK_STATE_DISABLED)) {
	    GradientFillRoundedRectangle(context, arrowBounds, 4,
		darkSelectedGradient, 2);
	}
	if (kind == kThemePopupButton) {
	    DrawUpDownArrows(context, arrowBounds, 3, 7, whiteRGBA);
	    DrawUpDownArrows(context, arrowBounds, 3, 7, WHITERGBA);
	} else {
	    DrawDownArrow(context, arrowBounds, 4, 8, whiteRGBA);
	    DrawDownArrow(context, arrowBounds, 4, 8, WHITERGBA);
	}
    }

    HighlightButtonBorder(context, bounds);
}

/*----------------------------------------------------------------------
769
770
771
772
773
774
775
776

777
778
779
780
781
782
783
813
814
815
816
817
818
819

820
821
822
823
824
825
826
827







-
+







	    clip.origin.y += clip.size.height;
	}
	CGContextClipToRect(context, clip);
	GradientFillRoundedRectangle(context, bounds, 5,
	    darkSelectedGradient, 2);
	CGContextRestoreGState(context);
    }
    DrawUpDownArrows(context, bounds, 3, 5, whiteRGBA);
    DrawUpDownArrows(context, bounds, 3, 5, WHITERGBA);
    HighlightButtonBorder(context, bounds);
}

/*----------------------------------------------------------------------
 * +++ DrawDarkBevelButton --
 *
 *      This is a standalone drawing procedure which draws RoundedBevelButtons
1036
1037
1038
1039
1040
1041
1042
1043

1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1080
1081
1082
1083
1084
1085
1086

1087
1088
1089
1090
1091
1092
1093

1094
1095
1096
1097
1098
1099
1100







-
+






-







 *      This is a standalone drawing procedure which draws a separator widget
 *      in Dark Mode.
 */

static void DrawDarkSeparator(
    CGRect bounds,
    CGContextRef context,
    Tk_Window tkwin)
    TCL_UNUSED(Tk_Window))
{
    static CGFloat fill[4] = {1.0, 1.0, 1.0, 0.3};
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *fillColor = [NSColor colorWithColorSpace: deviceRGB
	components: fill
	count:4];
    (void)tkwin;

    CGContextSetFillColorWithColor(context, CGCOLOR(fillColor));
    CGContextFillRect(context, bounds);
}

/*----------------------------------------------------------------------
 * +++ DrawDarkFocusRing --
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
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







-
+




-




+
-
+

-
+
-







 *      This is a standalone drawing procedure which draws column
 *      headers for a Treeview in the Dark Mode.
 */

static void DrawDarkListHeader(
    CGRect bounds,
    CGContextRef context,
    Tk_Window tkwin,
    TCL_UNUSED(Tk_Window),
    int state)
{
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *stroke;
    (void)tkwin;

    CGContextSetStrokeColorSpace(context, deviceRGB.CGColorSpace);
    CGFloat x = bounds.origin.x, y = bounds.origin.y;
    CGFloat w = bounds.size.width, h = bounds.size.height;

    CGPoint top[2] = {{x, y}, {x + w, y}};
    CGPoint top[2] = {{x, y + 1}, {x + w, y + 1}};
    CGPoint bottom[2] = {{x, y + h}, {x + w, y + h}};
    CGPoint separator[2] = {{x + w, y + 3}, {x + w, y + h - 3}};
    CGPoint separator[2] = {{x + w - 1, y + 3}, {x + w - 1, y + h - 3}};

    CGContextSaveGState(context);
    CGContextSetShouldAntialias(context, false);
    stroke = [NSColor colorWithColorSpace: deviceRGB
	components: darkFrameBottom
	count: 4];
    CGContextSetStrokeColorWithColor(context, CGCOLOR(stroke));
    CGContextBeginPath(context);
1198
1199
1200
1201
1202
1203
1204
1205

1206
1207

1208
1209
1210
1211
1212
1213
1214
1240
1241
1242
1243
1244
1245
1246

1247
1248

1249
1250
1251
1252
1253
1254
1255
1256







-
+

-
+








    if (state & TTK_TREEVIEW_STATE_SORTARROW) {
	CGRect arrowBounds = bounds;

	arrowBounds.origin.x = bounds.origin.x + bounds.size.width - 16;
	arrowBounds.size.width = 16;
	if (state & TTK_STATE_ALTERNATE) {
	    DrawUpArrow(context, arrowBounds, 3, 8, whiteRGBA);
	    DrawUpArrow(context, arrowBounds, 3, 8, WHITERGBA);
	} else if (state & TTK_STATE_SELECTED) {
	    DrawDownArrow(context, arrowBounds, 3, 8, whiteRGBA);
	    DrawDownArrow(context, arrowBounds, 3, 8, WHITERGBA);
	}
    }
}

/*----------------------------------------------------------------------
 * +++ Button element: Used for elements drawn with DrawThemeButton.
 */
1304
1305
1306
1307
1308
1309
1310
1311

1312
1313
1314
1315
1316
1317
1318
1346
1347
1348
1349
1350
1351
1352

1353
1354
1355
1356
1357
1358
1359
1360







-
+







    int *minWidth,
    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.
         */

1701
1702
1703
1704
1705
1706
1707
1708

1709
1710
1711
1712
1713
1714
1715
1743
1744
1745
1746
1747
1748
1749

1750
1751
1752
1753
1754
1755
1756
1757







-
+







#define ENTRY_DEFAULT_BACKGROUND "systemTextBackgroundColor"

static Ttk_ElementOptionSpec EntryElementOptions[] = {
    {"-background", TK_OPTION_BORDER,
     offsetof(EntryElement, backgroundObj), ENTRY_DEFAULT_BACKGROUND},
    {"-fieldbackground", TK_OPTION_BORDER,
     offsetof(EntryElement, fieldbackgroundObj), ENTRY_DEFAULT_BACKGROUND},
    {0}
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};

static void EntryElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *),
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
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







-
+
+




-
+






+
+
+
-
+
+




















-

-
+
+
+
+

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







 *      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),
    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 *),
    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,
2061
2062
2063
2064
2065
2066
2067
2068

2069
2070
2071
2072
2073
2074
2075
2113
2114
2115
2116
2117
2118
2119

2120
2121
2122
2123
2124
2125
2126
2127







-
+







} 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},
    {0, 0, 0, NULL}
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};
static void TrackElementSize(
    void *clientData,
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
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
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







+







+
+
+
+
+
+



-
+







    Ttk_Box b,
    Ttk_State state)
{
    TrackElementData *data = clientData;
    TrackElement *elem = elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;
    double from = 0, to = 100, value = 0, factor;
    CGRect bounds;

    TtkGetOrientFromObj(NULL, elem->orientObj, &orientation);
    Tcl_GetDoubleFromObj(NULL, elem->fromObj, &from);
    Tcl_GetDoubleFromObj(NULL, elem->toObj, &to);
    Tcl_GetDoubleFromObj(NULL, elem->valueObj, &value);
    factor = RangeToFactor(to);

    /*
     * HIThemeTrackDrawInfo uses 2-byte alignment; assigning to a separate
     * bounds variable avoids UBSan (-fsanitize=alignment) complaints.
     */

    bounds = BoxToRect(d, b);
    HIThemeTrackDrawInfo info = {
	.version = 0,
	.kind = data->kind,
	.bounds = BoxToRect(d, b),
	.bounds = bounds,
	.min = from * factor,
	.max = to * factor,
	.value = value * factor,
	.attributes = kThemeTrackShowThumb |
	    (orientation == TTK_ORIENT_HORIZONTAL ?
	    kThemeTrackHorizontal : 0),
	.enableState = Ttk_StateTableLookup(ThemeTrackEnableTable, state),
2122
2123
2124
2125
2126
2127
2128
2129

2130
2131
2132
2133
2134
2135
2136
2181
2182
2183
2184
2185
2186
2187

2188
2189
2190
2191
2192
2193
2194
2195







-
+







	    info.trackInfo.slider.thumbDir = kThemeThumbDownward;
	} else {
	    info.trackInfo.slider.thumbDir = kThemeThumbPlain;
	}
    }
    BEGIN_DRAWING(d)
    if (TkMacOSXInDarkMode(tkwin)) {
	CGRect bounds = BoxToRect(d, b);
	bounds = BoxToRect(d, b);
	NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
	NSColor *trackColor = [NSColor colorWithColorSpace: deviceRGB
	    components: darkTrack
	    count: 4];
	if (orientation == TTK_ORIENT_HORIZONTAL) {
	    bounds = CGRectInset(bounds, 1, bounds.size.height / 2 - 2);
	} else {
2201
2202
2203
2204
2205
2206
2207
2208

2209
2210
2211
2212
2213
2214
2215
2260
2261
2262
2263
2264
2265
2266

2267
2268
2269
2270
2271
2272
2273
2274







-
+







     offsetof(PbarElement, valueObj), "0"},
    {"-maximum", TK_OPTION_DOUBLE,
     offsetof(PbarElement, maximumObj), "100"},
    {"-phase", TK_OPTION_INT,
     offsetof(PbarElement, phaseObj), "0"},
    {"-mode", TK_OPTION_STRING,
     offsetof(PbarElement, modeObj), "determinate"},
    {0, 0, 0, 0}
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};
static void PbarElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
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
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







-
-
+
+
+
+
+
+
+
+


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

+


-
+
-
-
-
-
+

-
-
+
+

-
+
-

-
+

-


-
+







    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;

    /*
     * Using 1000 as the maximum should give better than 1 pixel
     * resolution for most progress bars.
     */

    int kind, phase = 0, ivalue, imaximum = 1000;
    CGRect bounds;

    TtkGetOrientFromObj(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);
	Tcl_GetDoubleFromObj(NULL, pbar->valueObj, &value);
	Tcl_GetDoubleFromObj(NULL, pbar->maximumObj, &maximum);
	ivalue = (value / maximum)*1000;
    }

    factor = RangeToFactor(maximum);
    /*
     * HIThemeTrackDrawInfo uses 2-byte alignment; assigning to a separate
     * bounds variable avoids UBSan (-fsanitize=alignment) complaints.
     */

    bounds = BoxToRect(d, b);
    HIThemeTrackDrawInfo info = {
	.version = 0,
	.kind =
	.kind = kind,
	    (!strcmp("indeterminate",
	    Tcl_GetString(pbar->modeObj)) && value) ?
	    kThemeIndeterminateBar : kThemeProgressBar,
	.bounds = BoxToRect(d, b),
	.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)) {
	CGRect bounds = BoxToRect(d, b);
	bounds = BoxToRect(d, b);
	NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
	NSColor *trackColor = [NSColor colorWithColorSpace: deviceRGB
	    components: darkTrack
	    count: 4];
	if (orientation == TTK_ORIENT_HORIZONTAL) {
	    bounds = CGRectInset(bounds, 1, bounds.size.height / 2 - 3);
	} else {
2291
2292
2293
2294
2295
2296
2297
2298

2299
2300
2301
2302
2303
2304
2305
2373
2374
2375
2376
2377
2378
2379

2380
2381
2382
2383
2384
2385
2386
2387







-
+







{
    Tcl_Obj *orientObj;
} ScrollbarElement;

static Ttk_ElementOptionSpec ScrollbarElementOptions[] = {
    {"-orient", TK_OPTION_STRING,
     offsetof(ScrollbarElement, orientObj), "horizontal"},
    {0, 0, 0, 0}
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};
static void TroughElementSize(
    TCL_UNUSED(void *),
    void *elementRecord,
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
2448
2449
2450
2451
2452
2453
2454
2455

2456
2457
2458
2459
2460
2461
2462
2530
2531
2532
2533
2534
2535
2536

2537
2538
2539
2540
2541
2542
2543
2544







-
+







	    components: rgba
	    count: 4];
	BEGIN_DRAWING(d)
	SolidFillRoundedRectangle(dc.context, thumbBounds, 4, thumbColor);
	END_DRAWING
    } else {
	double thumbSize, trackSize, visibleSize, factor, fraction;
	MacDrawable *macWin = (MacDrawable *) Tk_WindowId(tkwin);
	MacDrawable *macWin = (MacDrawable *)Tk_WindowId(tkwin);
	CGRect troughBounds = {{macWin->xOff, macWin->yOff},
			       {Tk_Width(tkwin), Tk_Height(tkwin)}};

        /*
         * The info struct has integer fields, which will be converted to
         * floats in the drawing routine.  All of values provided in the info
         * struct, namely min, max, value, and viewSize are only defined up to
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
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







-
+









-
+







    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"},
    {NULL, 0, 0, NULL}
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};

static void FieldElementDraw(
    TCL_UNUSED(void *),
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
2998
2999
3000
3001
3002
3003
3004












3005

3006

3007
3008
3009
3010
3011
3012
3013
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







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

+







	    .state = triangleState,
	    .kind = kThemeDisclosureTriangle,
	    .value = Ttk_StateTableLookup(DisclosureValueTable, state),
	    .adornment = kThemeAdornmentDrawIndicatorOnly,
	};

	BEGIN_DRAWING(d)
	if ([NSApp macOSVersion] >= 110000) {
	    CGFloat rgba[4];
	    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
	    NSColor *stroke = [[NSColor textColor]
		colorUsingColorSpace: deviceRGB];
	    [stroke getComponents: rgba];
	    if (state & TTK_TREEVIEW_STATE_OPEN) {
		DrawOpenDisclosure(dc.context, bounds, 2, 8, rgba);
	    } else {
		DrawClosedDisclosure(dc.context, bounds, 2, 12, rgba);
	    }
	} else {
	ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation,
	    ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation,
	    NULL);
	}
	END_DRAWING
    }
}

static Ttk_ElementSpec DisclosureElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
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
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







-
-
+
+






-
-
+
+



-
+







    TTK_GROUP("Combobox.button", TTK_FILL_BOTH,
    TTK_GROUP("Combobox.padding", TTK_FILL_BOTH,
    TTK_NODE("Combobox.textarea", TTK_FILL_BOTH))))

/* Notebook tabs -- no focus ring */
TTK_LAYOUT("Tab",
    TTK_GROUP("Notebook.tab", TTK_FILL_BOTH,
    TTK_GROUP("Notebook.padding", TTK_EXPAND | TTK_FILL_BOTH,
    TTK_NODE("Notebook.label", TTK_EXPAND | TTK_FILL_BOTH))))
    TTK_GROUP("Notebook.padding", TTK_FILL_BOTH,
    TTK_NODE("Notebook.label", TTK_FILL_BOTH))))

/* Spinbox -- buttons 2px to the right of the field. */
TTK_LAYOUT("TSpinbox",
    TTK_GROUP("Spinbox.buttons", TTK_PACK_RIGHT,
    TTK_NODE("Spinbox.uparrow", TTK_PACK_TOP | TTK_STICK_E)
    TTK_NODE("Spinbox.downarrow", TTK_PACK_BOTTOM | TTK_STICK_E))
    TTK_GROUP("Spinbox.field", TTK_EXPAND | TTK_FILL_X,
    TTK_NODE("Spinbox.textarea", TTK_EXPAND | TTK_FILL_X)))
    TTK_GROUP("Spinbox.field", TTK_FILL_X,
    TTK_NODE("Spinbox.textarea", TTK_FILL_X)))

/* Progress bars -- track only */
TTK_LAYOUT("TProgressbar",
    TTK_NODE("Progressbar.track", TTK_EXPAND | TTK_FILL_BOTH))
    TTK_NODE("Progressbar.track", TTK_FILL_BOTH))

/* Treeview -- no border. */
TTK_LAYOUT("Treeview",
    TTK_GROUP("Treeview.field", TTK_FILL_BOTH,
    TTK_GROUP("Treeview.padding", TTK_FILL_BOTH,
    TTK_NODE("Treeview.treearea", TTK_FILL_BOTH))))

3087
3088
3089
3090
3091
3092
3093
3094

3095
3096
3097
3098
3099
3100
3101

3102
3103
3104
3105
3106
3107
3108
3109
3182
3183
3184
3185
3186
3187
3188

3189

3190
3191
3192
3193
3194

3195

3196
3197
3198
3199
3200
3201
3202







-
+
-





-
+
-







    TTK_NODE("Treeitem.image", TTK_PACK_LEFT)
    TTK_NODE("Treeitem.text", TTK_PACK_LEFT)))

/* Scrollbar Layout -- Buttons at the bottom (Snow Leopard and Lion only) */

TTK_LAYOUT("Vertical.TScrollbar",
    TTK_GROUP("Vertical.Scrollbar.trough", TTK_FILL_Y,
    TTK_NODE("Vertical.Scrollbar.thumb",
    TTK_NODE("Vertical.Scrollbar.thumb", TTK_FILL_BOTH)
    TTK_PACK_TOP | TTK_EXPAND | TTK_FILL_BOTH)
    TTK_NODE("Vertical.Scrollbar.downarrow", TTK_PACK_BOTTOM)
    TTK_NODE("Vertical.Scrollbar.uparrow", TTK_PACK_BOTTOM)))

TTK_LAYOUT("Horizontal.TScrollbar",
    TTK_GROUP("Horizontal.Scrollbar.trough", TTK_FILL_X,
    TTK_NODE("Horizontal.Scrollbar.thumb",
    TTK_NODE("Horizontal.Scrollbar.thumb", TTK_FILL_BOTH)
    TTK_PACK_LEFT | TTK_EXPAND | TTK_FILL_BOTH)
    TTK_NODE("Horizontal.Scrollbar.rightarrow", TTK_PACK_RIGHT)
    TTK_NODE("Horizontal.Scrollbar.leftarrow", TTK_PACK_RIGHT)))

TTK_END_LAYOUT_TABLE

/*----------------------------------------------------------------------
 * +++ Initialization --

Changes to tests/all.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
20

21






-
+




-
+




-
+

+
+
-
+
# all.tcl --
#
# This file contains a top-level script to run all of the Tk
# tests.  Execute it by invoking "source all.tcl" when running tktest
# in this directory.
#
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 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.

package require Tk ;# This is the Tk test suite; fail early if no Tk!
package require tk ;# This is the Tk test suite; fail early if no Tk!
package require tcltest 2.2
tcltest::configure {*}$argv
tcltest::configure -testdir [file normalize [file dirname [info script]]]
tcltest::configure -loadfile \
	[file join [tcltest::testsDirectory] constraints.tcl]
    [file join [tcltest::testsDirectory] constraints.tcl]
tcltest::configure -singleproc 1
set ErrorOnFailures [info exists env(ERROR_ON_FAILURES)]
encoding system utf-8
tcltest::runAllTests
if {[tcltest::runAllTests] && $ErrorOnFailures} {exit 1}

Changes to tests/bell.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 "bell" command.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1998-2000 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1998-2000 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

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 (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 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
1
2
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 Tk's "bind" and "bindtags"
# commands plus the procedures in tkBind.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 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]}]
testConstraint needsTcl87 [package vsatisfies [package provide Tcl] 8.7]
testConstraint failsOnWindows [expr {![info exists ::env(CI)] || [tk windowingsystem] ne "win32"}]


toplevel .t -width 100 -height 50
wm geom .t +0+0
update idletasks

foreach p [event info] {event delete $p}
foreach event [bind Test] {
380
381
382
383
384
385
386
387

388
389
390
391
392
393

394
395
396
397
398
399
400
385
386
387
388
389
390
391

392
393
394
395
396
397

398
399
400
401
402
403
404
405







-
+





-
+







    .t.c bind foo a
} -cleanup {
    destroy .t.c
} -result {Test}

test bind-11.1 {Tk_GetAllBindings procedure} -body {
    frame .t.f
    foreach i "! a \\\{ ~ <Delete> <space> <<Paste>> <Tab> <Linefeed> <less> <Meta-a> <Acircumflex>" {
    foreach i "! a \\\{ ~ <Delete> <space> <<Paste>> <Tab> <Linefeed> <Key-<> <Meta-a> <Â>" {
        bind .t.f $i Test
    }
    lsort [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {! <<Paste>> <Key-Acircumflex> <Key-Delete> <Key-Linefeed> <Key-Tab> <Key-less> <Key-space> <Meta-Key-a> a \{ ~}
} -result "! <<Paste>> <Key-<> <Key-Delete> <Key-Linefeed> <Key-Tab> <Key-space> <Key-Â> <Meta-Key-a> a \\\{ ~"
test bind-11.2 {Tk_GetAllBindings procedure} -body {
    frame .t.f
    foreach i "<Double-Button-1> <Triple-Button-1> <Meta-Control-a> <Double-Alt-Enter> <Button-1>" {
        bind .t.f $i Test
    }
    lsort [bind .t.f]
} -cleanup {
432
433
434
435
436
437
438
439
440
441



442
443
444
445
446
447
448
449

450
451
452
453
454
455
456
457
458
459
460
461
462

463
464
465
466
467
468

469
470
471
472
473
474
475
476
477
478
479
480

481
482
483
484
485
486
487

488
489
490
491
492
493
494

495
496
497
498
499
500
501
502
503
504
505
506
507
508
509

510
511
512
513
514
515
516
437
438
439
440
441
442
443



444
445
446
447
448
449
450
451
452
453

454
455
456
457
458
459
460
461
462
463
464
465
466

467
468
469
470
471
472

473
474
475
476
477
478
479
480
481
482
483
484

485
486
487
488
489
490
491

492
493
494
495
496
497
498

499
500
501
502
503
504
505
506
507
508
509
510
511
512
513

514
515
516
517
518
519
520
521







-
-
-
+
+
+







-
+












-
+





-
+











-
+






-
+






-
+














-
+







} -body {
    bind Test <Key> {lappend x "%W %K Test Key"}
    bind all <Key> {lappend x "%W %K all Key"}
    bind Test : {lappend x "%W %K Test :"}
    bind all  _ {lappend x "%W %K all _"}
    bind .t.f : {lappend x "%W %K .t.f :"}

    event generate .t.f <colon>
    event generate .t.f <plus>
    event generate .t.f <underscore>
    event generate .t.f <:>
    event generate .t.f <+>
    event generate .t.f <_>
    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 : .t.f :} {.t.f : Test :} {.t.f : all Key} {.t.f + Test Key} {.t.f + all Key} {.t.f _ Test Key} {.t.f _ 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 <:>
    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}}
} -result {{.t.f : .t.f pressed colon} {.t.f : 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 <:>
    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
}  -result {{{.t.f : .t.f pressed colon} {.t.f : 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 <:>
    }
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind Test : {lappend x "%W %K Test"}
    bind .t.f : {lappend x "%W %K .t.f"}
    foo
    return $x
} -cleanup {
    destroy .t.f
    bind Test : {}
} -result {{.t.f colon .t.f} {.t.f colon Test}}
} -result {{.t.f : .t.f} {.t.f : Test}}

test bind-13.5 {Tk_BindEvent procedure} -body {
    bind all <Destroy> {lappend x "%W destroyed"}
    set x {}
    frame .t.g -gorp foo
} -cleanup {
    bind all <Destroy> {}
530
531
532
533
534
535
536
537

538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554

555
556
557
558
559
560
561
535
536
537
538
539
540
541

542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558

559
560
561
562
563
564
565
566







-
+
















-
+







    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 <:>
    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 <:>
    return $x
} -cleanup {
    bind Test : {}
    bind all : {}
    destroy .t.f
} -result {{.t.f (.t.f binding)} {.t.f (Test binding)} {.t.f (all binding)}}

629
630
631
632
633
634
635
636
637


638
639
640
641

642
643
644
645
646
647
648
634
635
636
637
638
639
640


641
642
643
644
645

646
647
648
649
650
651
652
653







-
-
+
+



-
+







    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x Key%K"
    bind .t.f <KeyRelease> "lappend x Release%K"
    event generate .t.f <Key> -keysym colon
    event generate .t.f <KeyRelease> -keysym colon
    event generate .t.f <Key> -keysym :
    event generate .t.f <KeyRelease> -keysym :
    return $x
} -cleanup {
    destroy .t.f
} -result {Keycolon Releasecolon}
} -result {Key: Release:}
test bind-13.14 {Tk_BindEvent procedure: invalid key detail} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
2044
2045
2046
2047
2048
2049
2050
2051

2052
2053
2054
2055
2056
2057
2058
2049
2050
2051
2052
2053
2054
2055

2056
2057
2058
2059
2060
2061
2062
2063







-
+







    event generate .t.f <braceleft> -state 1
    event generate .t.f <Multi_key>
    event generate .t.f <e>
    event generate .t.f <apostrophe>
    set x
} -cleanup {
    destroy .t.f
} -result {a A {	} {\r} {{}} {{}} { } {\$} \\\{ {{}} {{}} \u00e9}
} -result {a A {	} {\r} {{}} {{}} { } {\$} \\\{ {{}} {{}} é}
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"}
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
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







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
















-
+







    list $x $y $z
} -cleanup {
    destroy .t.e
    bind Entry <Key> $savedBind(Entry)
    bind all <Key> $savedBind(All)
    unset savedBind
} -result {0 1 2}
test bind-16.47 {ExpandPercents procedure} -constraints {aquaOrWin32 needsTcl87 failsOnWindows} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Key> {set x "%K"}
    set x none
    event generate .t.f <Key> -keysym €
    set x
} -cleanup {
    destroy .t.f
} -result €

test bind-17.1 {event command} -body {
    event
} -returnCodes error -result {wrong # args: should be "event option ?arg?"}
test bind-17.2 {event command} -body {
    event xyz
} -returnCodes error -result {bad option "xyz": must be add, delete, generate, or info}
test bind-17.3 {event command: add} -body {
    event add
} -returnCodes error -result {wrong # args: should be "event add virtual sequence ?sequence ...?"}
test bind-17.4 {event command: add 1} -body {
    event delete <<Paste>>
    event add <<Paste>> <Control-v>
    event info <<Paste>>
} -cleanup {
    event delete <<Paste>> <Control-v>
} -result {<Control-Key-v>}
} -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>}
2345
2346
2347
2348
2349
2350
2351
2352

2353
2354
2355
2356
2357
2358
2359
2360

2361
2362
2363
2364
2365
2366
2367
2363
2364
2365
2366
2367
2368
2369

2370
2371
2372
2373
2374
2375
2376
2377

2378
2379
2380
2381
2382
2383
2384
2385







-
+







-
+







} -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>>
2402
2403
2404
2405
2406
2407
2408
2409

2410
2411
2412
2413
2414
2415
2416
2420
2421
2422
2423
2424
2425
2426

2427
2428
2429
2430
2431
2432
2433
2434







-
+







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







-
+




















-
+







test bind-20.3 {GetVirtualEvent procedure: owns 1} -setup {
    event delete <<xyz>>
} -body {
    event add <<xyz>> <Control-v>
    event info <<xyz>>
} -cleanup {
    event delete <<xyz>>
} -result {<Control-Key-v>}
} -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>
    lsort [event info]
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
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







-
+



















-
+







} -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}
5186
5187
5188
5189
5190
5191
5192
5193

5194
5195
5196
5197
5198
5199
5200
5204
5205
5206
5207
5208
5209
5210

5211
5212
5213
5214
5215
5216
5217
5218







-
+







} -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
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
5549
5550
5551
5552
5553
5554
5555














5556
5557
5558
5559
5560
5561
5562







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







    set x xyzzy
    event generate .t.f <Button>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Button} <Button>}

test bind-26.6 {event names: ButtonPress} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <ButtonPress> "set x {event ButtonPress}"
    set x xyzzy
    event generate .t.f <ButtonPress>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -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 {
    bind .t.f <ButtonRelease> "set x {event ButtonRelease}"
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
5633
5634
5635
5636
5637
5638
5639














5640
5641
5642
5643
5644
5645
5646







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







    set x xyzzy
    event generate .t.f <Key>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Key} <Key>}

test bind-26.13 {event names: KeyPress} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <KeyPress> "set x {event KeyPress}"
    set x xyzzy
    event generate .t.f <KeyPress>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event KeyPress} <Key>}

test bind-26.14 {event names: KeyRelease} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <KeyRelease> "set x {event KeyRelease}"
5956
5957
5958
5959
5960
5961
5962
5963
5964


5965
5966

5967
5968
5969
5970
5971
5972
5973
5946
5947
5948
5949
5950
5951
5952


5953
5954
5955

5956
5957
5958
5959
5960
5961
5962
5963







-
-
+
+

-
+








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 <:> "lappend x \"keysym received\""
    bind .t.f <_> "lappend x {bad binding match}"
    set x [lsort [bind .t.f]]
    event generate .t.f <colon> ;# -state 0
    event generate .t.f <:> ;# -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
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
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







-
+

-
+



-
-
+
+

-
+



-
+






-
+






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







    bind .t.f <x> "lappend x {bad binding match}"
    set x [lsort [bind .t.f]]
    event generate .t.f <X> -state 1
    set x
} -cleanup {
    destroy .t.f
} -result {X x {keysym X}}
test bind-28.9 {keysym names, Eth -> ETH} -body {
test bind-28.9 {keysym names, Ð} -body {
    frame .t.f -class Test -width 150 -height 100
    bind .t.f <Eth> foo
    bind .t.f <Ð> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result {<Key-ETH>}
test bind-28.10 {keysym names, Ooblique -> Oslash} -body {
} -result <Key-Ð>
test bind-28.10 {keysym names, Ø} -constraints nodeprecated -body {
    frame .t.f -class Test -width 150 -height 100
    bind .t.f <Ooblique> foo
    bind .t.f <Ø> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result {<Key-Oslash>}
} -result <Key-Ø>
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-28.13 {keysym names, Unicode} -body {
    frame .t.f -class Test -width 150 -height 100
    bind .t.f <€> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result "<Key-€>"
test bind-28.14 {keysym names, Emoji} -body {
    frame .t.f -class Test -width 150 -height 100
    bind .t.f <\U1F44D> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result "<Key-\U1F44D>"
test bind-28.15 {keysym names, Emoji} -constraints needsTcl87 -body {
    frame .t.f -class Test -width 150 -height 100
    bind .t.f <👍> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result "<Key-👍>"


test bind-29.1 {Tcl_BackgroundError procedure} -setup {
    proc bgerror msg {
        global x errorInfo
        set x [list $msg $errorInfo]
    }
6225
6226
6227
6228
6229
6230
6231


6232
6233
6234
6235
6236
6237

6238
6239
6240
6241
6242
6243
6244
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258







+
+






+







    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
    after 50  ; # Win specific - wait for SendInput to be executed
    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]
6758
6759
6760
6761
6762
6763
6764
6765

6766
6767
6768
6769
6770
6771
6772
6772
6773
6774
6775
6776
6777
6778

6779
6780
6781
6782
6783
6784
6785
6786







-
+







test bind-33.19 {simulate use of the keyboard to trigger a pattern sequence with modifier - bug [16ef161925]} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Escape><Control-c> { lappend x "Esc_Control-c" }
    bind .t.f <Escape><KeyPress><KeyPress><Control-c> { lappend x "Esc_Key(2)_Control-c" }
    bind .t.f <Escape><Key><Key><Control-c> { lappend x "Esc_Key(2)_Control-c" }
    event generate .t.f <Escape>
    event generate .t.f <Alt_L>
    event generate .t.f <Control_L>
    event generate .t.f <Control-c>
    set x
} -cleanup {
    destroy .t.f
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820


6821
6822
6823
6824
6825
6826


6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844

6845
6846
6847
6848

6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867

6868
6869
6870
6871
6872
6873
6874
6875
6876

6877
6878

6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896

6897
6898
6899
6900
6901
6902
6903
6825
6826
6827
6828
6829
6830
6831



6832
6833
6834
6835
6836



6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854


6855
6856
6857


6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875


6876
6877
6878
6879
6880
6881
6882
6883
6884

6885
6886

6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904

6905
6906
6907
6908
6909
6910
6911
6912







-
-
-
+
+



-
-
-
+
+
















-
-
+


-
-
+

















-
-
+








-
+

-
+

















-
+







    # In order to avoid platform-dependent coordinate results due to
    # decorations and borders, this test warps the pointer twice
    # relatively to a window that moved in the meantime, and checks
    # how much the pointer moved
    wm geometry .top +200+200
    update
    event generate .top <Motion> -x 20 -y 20 -warp 1
    update idletasks ; # DoWarp is an idle callback
    after 50         ; # Win specific - wait for SendInput to be executed
    set pointerPos1 [winfo pointerxy .t]
    after 50  ; # Win specific - wait for SendInput to be executed
    set pointerPos1 [winfo pointerxy .top]
    wm geometry .top +600+600
    update
    event generate .top <Motion> -x 20 -y 20 -warp 1
    update idletasks ; # DoWarp is an idle callback
    after 50         ; # Win specific - wait for SendInput to be executed
    set pointerPos2 [winfo pointerxy .t]
    after 50  ; # Win specific - wait for SendInput to be executed
    set pointerPos2 [winfo pointerxy .top]
    # from the first warped position to the second one, the mouse
    # pointer should have moved the same amount as the window moved
    set res 1
    foreach pos1 $pointerPos1 pos2 $pointerPos2 {
        if {$pos1 != [expr {$pos2 - 400}]} {
            set res [list $pointerPos1 $pointerPos2]
        }
    }
    set res
} -cleanup {
    destroy .top
} -result 1
test bind-34.2 {-warp works relatively to the screen} -setup {
} -body {
    # Contrary to bind-34.1, we're directly checking screen coordinates
    event generate {} <Motion> -x 20 -y 20 -warp 1
    update idletasks ; # DoWarp is an idle callback
    after 50         ; # Win specific - wait for SendInput to be executed
    after 50  ; # Win specific - wait for SendInput to be executed
    set res [winfo pointerxy .]
    event generate {} <Motion> -x 200 -y 200 -warp 1
    update idletasks ; # DoWarp is an idle callback
    after 50         ; # Win specific - wait for SendInput to be executed
    after 50  ; # Win specific - wait for SendInput to be executed
    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
    update idletasks ; # DoWarp is an idle callback
    after 50         ; # Win specific - wait for SendInput to be executed
    after 50  ; # Win specific - wait for SendInput to be executed
    foreach dim [winfo pointerxy .] {
        if {$dim <= $halo} {
            lappend res ok
        } else {
            lappend res $dim
        }
    }
    event generate {} <Motion> -x 100 -y 100 -warp 1
    update idletasks ; after 50
    after 50  ; # Win specific - wait for SendInput to be executed
    event generate {} <Motion> -x -1 -y -1 -warp 1
    update idletasks ; after 50
    after 50  ; # Win specific - wait for SendInput to be executed
    foreach dim [winfo pointerxy .] {
        if {$dim <= $halo} {
            lappend res ok
        } else {
            lappend res $dim
        }
    }
    set res
} -cleanup {
} -result {ok ok ok ok}

set keyInfo {}
set numericKeysym {}
proc testKey {window event type mods} {
    global keyInfo numericKeysym
    set keyInfo {}
    set numericKeysym {}
    bind $window <KeyPress> {
    bind $window <Key> {
	set keyInfo [format "%K,0x%%X,0x%%X,%A" %N %k]
	set numericKeysym %N
    }
    focus -force $window
    update
    event generate $window $event
    if {$keyInfo == {}} {
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
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







-
-
+
+

















-
+







} -cleanup {
    destroy .new.e
    destroy .new
} -result pass

test bind-35.2 {Can bind to function keys} -constraints {aqua} -body {
    global keyInfo numericKeysym
    bind . <KeyPress> {}
    bind . <KeyPress> {
    bind . <Key> {}
    bind . <Key> {
	lappend keyInfo %K
	set numericKeysym %N
    }
    set keyInfo {}
    set numericKeysym {}
    focus -force .
    event generate . <F2>
    injectkeyevent press $numericKeysym -function
    vwait keyInfo
    return $keyInfo
} -cleanup {
} -result {F2 F2}

test bind-35.3 {Events agree for modifier keys} -constraints {aqua} -setup {
} -body {
    global keyInfo numericalKeysym
    set result {}
    bind . <KeyPress> {
    bind . <Key> {
    	set keyInfo [format "%K,0x%%X,0x%%X,%A" %N %k]
    	set numericalKeysym [format "0x%x" %N]
    }
    foreach event {
	{<Control_L> -control}
	{<Control_R> -control}
	{<Alt_L> -option}
7013
7014
7015
7016
7017
7018
7019



































7020
7021
7022
7023
7024
7025
7026
7027
7028
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







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









	if {$save != $keyInfo} {
	    return "$save != $keyInfo"
	}
    }
    return pass
} -cleanup {
} -result pass

test bind-36.1 {pointer warp with grab on toplevel, bug [e3888d5820]} -setup {
    event generate {} <Motion> -warp 1 -x 50 -y 50
    after 50  ; # Win specific - wait for SendInput to be executed
    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
    after 50  ; # Win specific - wait for SendInput to be executed
    foreach {x1 y1} [winfo pointerxy .top.l] {}
    event generate {} <Motion> -warp 1 -x 50 -y 50
    after 50  ; # Win specific - wait for SendInput to be executed
    grab release .top
    event generate .top.l <Motion> -warp 1 -x 10 -y 10
    after 50  ; # Win specific - wait for SendInput to be executed
    foreach {x2 y2} [winfo pointerxy .top.l] {}
    # success if the coords are the same with or without the grab, and if they
    # are at (10,10) inside the label widget as requested by the warping
    expr {$x1==$x2 && $y1==$y2 && $x1==[winfo rootx .top.l]+10 \
                               && $y1==[winfo rooty .top.l]+10}
} -cleanup {
    destroy .top
    unset x1 y1 x2 y2
} -result 1

# cleanup
cleanupTests
return

# vi:set ts=4 sw=4 et:
# Local Variables:
# mode: tcl
# End:

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 (c) 1998 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1998 Sun Microsystems, Inc.
# Copyright © 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 (c) 1998 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1998 Sun Microsystems, Inc.
# Copyright © 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
1
2
3
4
5
6

7
8

9
10
11
12
13
14
15
16
17
18
19

20
21
22
23

24
25
26
27
28
29
30
31






-
+

-
+










-
+



-
+







# 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 (c) 1998-2000 by Jos Decoster. All rights reserved.
# Copyright © 1998-2000 Jos Decoster. All rights reserved.

package require tcltest 2.1
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 arg ...?"}
} -result {wrong # args: should be "tk busy options ?arg ...?"}

test busy-2.1 {tk busy hold} -returnCodes error -body {
    tk busy hold
} -result {wrong # args: should be "tk busy hold window ?option value ...?"}
} -result {wrong # args: should be "tk busy hold window ?-option value ...?"}
test busy-2.2 {tk busy hold root window} -body {
    set res [tk busy hold .]
    update
    set res
} -cleanup {
    tk busy forget .
} -result {._Busy}
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







-
+







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

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 (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit

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 (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit
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







-
+







    .c itemconfigure i1 -image foo2
    update idletasks
    update
    # On MacOS we need to wait for the test image display procedure to run.
    while {"timed out" ni $y && [lindex $y end 1] ne "display"} {
        vwait y
    }
    after cancel timer
    after cancel $timer
    list $x $y [.c bbox i1]
} -cleanup {
    .c delete all
    image delete foo
    image delete foo2
} -result {{{foo free}} {{foo2 get} {foo2 display 0 0 80 60}} {50 100 130 160}}
test canvImg-4.3 {ConfiugreImage procedure} -constraints testImageType -setup {
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753

754
755
756
757
758
759
760
761
762
763
764
765

766
767
768
769
770
771
772
723
724
725
726
727
728
729






730
731
732
733
734
735
736
737
738
739
740
741

742
743
744
745

746
747
748
749
750
751
752
753
754
755
756
757

758
759
760
761
762
763
764
765







-
-
-
-
-
-












-




-
+











-
+







    .c scale image 25 0 2.0 1.5
    .c bbox image
} -cleanup {
	.c delete all
	image delete foo
} -result {75 150 105 165}

if {[tk windowingsystem] == "aqua" && $tcl_platform(osVersion) > 18} {
    # Aqua >= 10.14 will redraw the entire image.
    set result_10_1 {{foo display 0 0 30 15}}
} else {
    set result_10_1 {{foo display 2 4 6 8}}
}
test canvImg-10.1 {TranslateImage procedure} -constraints testImageType -setup {
    .c delete all
    update
} -body {
    image create test foo -variable x
    .c create image 50 100 -image foo -tags image -anchor nw
    update
    set x {}
    set timer [after 500 {lappend x "timed out"}]
    foo changed 2 4 6 8 30 15
    vwait x
    after cancel $timer
    update
    return $x
} -cleanup {
    .c delete all
    image delete foo
} -result $result_10_1
} -result {{foo display 2 4 6 8}}

test canvImg-11.1 {TranslateImage procedure} -constraints testImageType -setup {
    .c delete all
    update
} -body {
    image create test foo -variable x
    .c create image 50 100 -image foo -tags image -anchor nw
    update
    set x {}
    set timer [after 500 {lappend x "timed out"}]
    foo changed 2 4 6 8 40 50
        vwait x
    vwait x
    after cancel $timer
    update
    return $x
} -cleanup {
    .c delete all
    image delete foo
} -result {{foo display 0 0 40 50}}
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
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







-
-
-
-
-
-
+




-
+







-


-
-
+
+




-
-
+
+









    set x {}
    foo changed 0 0 0 0 40 50
    .c bbox image
} -cleanup {
	.c delete all
	image delete foo
} -result {30 75 70 125}
if {[tk windowingsystem] == "aqua" && $tcl_platform(osVersion) > 18} {
    # Aqua >= 10.14 will redraw the entire image.
    set result_11_3 {{foo2 display 0 0 80 60}}
} else {
    set result_11_3 {{foo2 display 0 0 20 40}}
}

test canvImg-11.3 {ImageChangedProc procedure} -constraints {
	testImageType
} -setup {
    .c delete all
    update
    update idletasks
} -body {
    image create test foo -variable x
    image create test foo2 -variable z
    foo changed 0 0 0 0 40 50
    foo2 changed 0 0 0 0 80 60
    .c create image 50 100 -image foo -tags image -anchor nw
    .c create image 70 110 -image foo2 -anchor nw
    update idletasks
    set z {}
    set timer [after 500 {lappend z "timed out"}]
    image create test foo -variable x
    vwait x
    image delete foo
    vwait z
    after cancel $timer
    return $z
} -cleanup {
    .c delete all
    image delete foo foo2
} -result $result_11_3
    image delete foo2
} -result {{foo2 display 0 0 80 60}}

# cleanup
imageFinish
cleanupTests
return

# Local variables:
# mode: tcl
# End:

Changes to tests/canvMoveto.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



-
-
-
+
+
+


-
+







# This file is a Tcl script to test out the canvas "moveto" command. It is
# derived from canvRect.test.
#
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright (c) 2004 Neil McKay.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# Copyright © 2004 Neil McKay.
# All rights reserved.

package require tcltest 2.1
package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

canvas .c -width 400 -height 300 -bd 2 -relief sunken
.c create rectangle 20 20 80 80 -tag {test rect1}
.c create rectangle 40 40 90 100 -tag {test rect2}

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 (c) 1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit

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 (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

Changes to tests/canvText.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




-
-
+
+






+
+
+







# This file is a Tcl script to test out the procedures in tkCanvText.c,
# which implement canvas "text" items.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright (c) 1996-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1996-1997 Sun Microsystems, Inc.
# Copyright © 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(CI)] || ![string match Linux $::tcl_platform(os)]}]
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
936
937
938
939
940
941
942
943

944
945
946
947
948
949
950
939
940
941
942
943
944
945

946
947
948
949
950
951
952
953







-
+







    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} -setup {
test canvText-20.1 {angled text bounding box} -constraints {failsOnUbuntu failsOnXQuarz} -setup {
    destroy .c
    canvas .c
    proc transpose {bbox} {
	lassign $bbox a b c d
	list $b $a $d $c
    }
} -body {

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 (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

Changes to tests/canvas.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 tkCanvas.c, which
# implements generic code for canvases. It is organized in the standard
# fashion for Tcl tests.
#
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 Ajuba Solutions.
# Copyright (c) 2008 Donal K. Fellows
# Copyright © 1995-1996 Sun Microsystems, Inc.
# Copyright © 1998-2000 Ajuba Solutions.
# Copyright © 2008 Donal K. Fellows
# All rights reserved.

package require tcltest 2.1
package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit

# XXX - This test file is woefully incomplete. At present, only a few of the
# features are tested.

350
351
352
353
354
355
356
















357
358
359
360
361
362
363
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379







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







    set coordBox [.c bbox arc2]
    .c create arc 300 10 500 210 -start 10 -extent 50 -style pieslice -tags arc3
    set pieBox [.c bbox arc3]
    .c create arc 100 200 300 200 -height [expr {(1-0.5*sqrt(3))*200}] -style arc -tags arc4
    set arcSegBox [.c bbox arc4]
    list $arcBox $coordBox $pieBox $arcSegBox
} -result {{48 21 100 94} {248 21 300 94} {398 21 500 112} {98 171 302 202}}
test canvas-8.2 {canvas very small arc} -setup {
    catch {destroy .c}
    canvas .c
} -body {
    # no Inf or NaN must be generated even for very small arcs
    .c create arc 0 100 0 100 -height 100 -style arc -outline "" -tags arc1
    set arcBox [.c bbox arc1]
    .c create arc 0 100 0 100 -height 100 -style arc -outline blue -tags arc2
    set outlinedArcBox [.c bbox arc2]
    set coords [.c coords arc1]
    set start [.c itemcget arc1 -start]
    set extent [.c itemcget arc1 -extent]
    set width [.c itemcget arc1 -width]
    set height [.c itemcget arc1 -height]
    list $arcBox $outlinedArcBox $coords $start $extent $width $height
} -result {{-1 99 1 101} {-2 98 2 102} {0.0 100.0 0.0 100.0} 0.0 0.0 1.0 0.0}

test canvas-9.1 {canvas id creation and deletion} -setup {
    catch {destroy .c}
    canvas .c
} -body {
    # With Tk 8.0.4 the ids are now stored in a hash table. You can use this
    # test as a performance test with older versions by changing the value of
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
1015
1016
1017
1018
1019
1020
1021










































































































1022
1023
1024
1025
1026
1027
1028







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







    .c itemconfigure 1 -tags {tagA tagA tagA tagA tagA tagA}
    set res [list [.c gettags 1]]
    .c dtag 1 tagA
    lappend res [.c gettags 1]
} -cleanup {
    destroy .c
} -result {{tagA tagA tagA tagA tagA tagA} {}}

# Procedure used in test cases 20.1 20.2 20.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-20.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-20.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-20.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

test canvas-21.1 {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}


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
1288
1289
1290
1291
1292
1293
1294
1295

























































































1296
1297
1298
1299
1300
1301
1302
1303
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







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








    .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 (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

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
1
2
3
4


5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31




-
-
+
+
















+
+







# This file is a Tcl script to test out Tk's clipboard management code,
# especially the "clipboard" command.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 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
}
229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
231
232
233
234
235
236
237

238
239
240
241
242
243
244
245







-
+







    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 -setup {
test clipboard-6.2 {Tk_ClipboardAppend procedure} -constraints {x11 failsOnXQuarz} -setup {
    clipboard clear
} -body {
    setupbg
    clipboard append -f INTEGER -t TEST "16"
    set result [dobg {clipboard get TEST}]
    return $result
} -cleanup {

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 (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 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/cmds.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
# tkCmds.c.  It is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 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/color.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 procedures in the file
# tkColor.c.  It is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1995-1998 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1995-1998 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.1
package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

# cname --
# Returns a proper name for a color, given its intensities.
#
# Arguments:
158
159
160
161
162
163
164
165

166
167
168
169
170
171
172
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172







-
+







    button .b2 -foreground $x -text Third
    pack .b2 -side top
    lappend result [testcolor purple]
} {{{1 1}} {{1 1} {1 0}} {{1 0} {2 1}}}
test color-1.5 {Color table} nonPortable {
    set fd [open ../xlib/rgb.txt]
    set result {}
    while {[gets $fd line] != -1} {
    while {[gets $fd line] >= 0} {
    	if {[string index $line 0] == "!"} continue
	set rgb [c255 [winfo rgb . [lrange $line 3 end]]]
	if {$rgb != [lrange $line 0 2] } {
		append result $line\n
	}

    }

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 (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

Changes to tests/constraints.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
1
2
3
4
5
6
7

8
9
10
11
12
13
14
15
16
17
18
19

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

40
41
42
43
44
45
46
47







-
+











-
+



















-
+







if {[namespace exists tk::test]} {
    deleteWindows
    wm geometry . {}
    raise .
    return
}

package require Tk 8.4
package require tk
tk appname tktest
wm title . tktest
# If the main window isn't already mapped (e.g. because the tests are
# being run automatically) , specify a precise size for it so that the
# user won't have to position it manually.

if {![winfo ismapped .]} {
    wm geometry . +0+0
    update
}

package require tcltest 2.1
package require tcltest 2.2

namespace eval tk {
    namespace eval test {

	namespace export loadTkCommand
	proc loadTkCommand {} {
	    set tklib {}
	    foreach pair [info loaded {}] {
		foreach {lib pfx} $pair break
		if {$pfx eq "Tk"} {
		    set tklib $lib
		    break
		}
	    }
	    return [list load $tklib Tk]
	}

	namespace eval bg {
	    # Manage a background process.
	    # Replace with slave interp or thread?
	    # Replace with child interp or thread?
	    namespace import ::tcltest::interpreter
	    namespace import ::tk::test::loadTkCommand
	    namespace export setup cleanup do

	    proc cleanup {} {
		variable fd
		# catch in case the background process has closed $fd
193
194
195
196
197
198
199
200
201


202
203
204
205
206
207
208
193
194
195
196
197
198
199


200
201
202
203
204
205
206
207
208







-
-
+
+







testConstraint haveDISPLAY [expr {[info exists env(DISPLAY)] && [testConstraint x11]}]
testConstraint altDisplay  [info exists env(TK_ALT_DISPLAY)]
testConstraint noExceed [expr {
    ![testConstraint unix] || [catch {font actual "\{xyz"}]
}]

# constraints for testing facilities defined in the tktest executable...
testConstraint testImageType [expr {[lsearch [image types] test] >= 0}]
testConstraint testOldImageType [expr {[lsearch [image types] oldtest] >= 0}]
testConstraint testImageType [expr {"test" in [image types]}]
testConstraint testOldImageType [expr {"oldtest" in [image types]}]
testConstraint testbitmap    [llength [info commands testbitmap]]
testConstraint testborder    [llength [info commands testborder]]
testConstraint testcbind     [llength [info commands testcbind]]
testConstraint testclipboard [llength [info commands testclipboard]]
testConstraint testcolor     [llength [info commands testcolor]]
testConstraint testcursor    [llength [info commands testcursor]]
testConstraint testembed     [llength [info commands testembed]]
243
244
245
246
247
248
249
250

251
252
253

254
255
256
257
258
259
260
243
244
245
246
247
248
249

250
251
252

253
254
255
256
257
258
259
260







-
+


-
+







testConstraint pseudocolor8 [expr {
    ([catch {
	toplevel .t -visual {pseudocolor 8} -colormap new
    }] == 0) && ([winfo depth .t] == 8)
}]
destroy .t
testConstraint haveTruecolor24 [expr {
    [lsearch -exact [winfo visualsavailable .] {truecolor 24}] >= 0
    {truecolor 24} in [winfo visualsavailable .]
}]
testConstraint haveGrayscale8 [expr {
    [lsearch -exact [winfo visualsavailable .] {grayscale 8}] >= 0
    {grayscale 8} in [winfo visualsavailable .]
}]
testConstraint defaultPseudocolor8 [expr {
    ([winfo visual .] eq "pseudocolor") && ([winfo depth .] == 8)
}]

# constraint based on whether our display is secure
setupbg

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 (c) 1998 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1998 Sun Microsystems, Inc.
# Copyright © 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.

56
57
58
59
60
61
62
63

64
65
66
67
56
57
58
59
60
61
62

63
64
65
66
67







-
+




    set x [after 5000 [list set tk::Priv(button) "no response"]]
    after 100 destroy .d
    set res [tk_dialog .d foo foo info 0 click]
    after cancel $x
    return $res
} -cleanup {
    destroy .b
} -result {-1}
} -result -1

cleanupTests
return

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 (c) 1996-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1996-1997 Sun Microsystems, Inc.
# Copyright © 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
1
2
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 entry widgets in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 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(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" }]

# For xscrollcommand
set scrollInfo {}
proc scroll args {
        global scrollInfo
        set scrollInfo $args
}
# For trace variable
proc override args {
        global x
744
745
746
747
748
749
750
751

752
753
754
755
756
757
758
759
760
761
762
763
764

765
766
767
768
769
770
771
749
750
751
752
753
754
755

756
757
758
759
760
761
762
763
764
765
766
767
768

769
770
771
772
773
774
775
776







-
+












-
+







	fonts
} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
# Tcl_UtfAtIndex(): utf at end
    .e insert 0 "ab\u4e4e"
    .e insert 0 "ab"
    .e bbox end
} -cleanup {
    destroy .e
} -result {19 5 12 13}
test entry-3.8 {EntryWidgetCmd procedure, "bbox" widget command} -constraints {
	fonts
} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
# Tcl_UtfAtIndex(): utf before index
    .e insert 0 "ab\u4e4ec"
    .e insert 0 "abc"
    .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
779
780
781
782
783
784
785
786

787
788
789
790
791
792
793
784
785
786
787
788
789
790

791
792
793
794
795
796
797
798







-
+







test entry-3.10 {EntryWidgetCmd procedure, "bbox" widget command} -constraints {
	fonts
} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert 0 "abcdefghij\u4e4eklmnop"
    .e insert 0 "abcdefghijklmnop"
    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 {
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
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







-
+



-
+



-
+




-
+







test entry-3.24 {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
    pack .e
    update
    set x {}
} -body {
# UTF
    .e insert end "01234\u4e4e67890"
    .e insert end "0123467890"
    .e delete 6
    lappend x [.e get]
    .e delete 0 end
    .e insert end "012345\u4e4e7890"
    .e insert end "0123457890"
    .e delete 6
    lappend x [.e get]
    .e delete 0 end
    .e insert end "0123456\u4e4e890"
    .e insert end "0123456890"
    .e delete 6
    lappend x [.e get]
} -cleanup {
    destroy .e
} -result [list "01234\u4e4e7890" "0123457890" "012345\u4e4e890"]
} -result [list "012347890" "0123457890" "012345890"]
test entry-3.25 {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e delete 6 5
1010
1011
1012
1013
1014
1015
1016
1017

1018
1019
1020
1021
1022
1023
1024
1015
1016
1017
1018
1019
1020
1021

1022
1023
1024
1025
1026
1027
1028
1029







-
+







} -returnCodes {ok} -match glob -result {*}
test entry-3.35 {EntryWidgetCmd procedure, "index" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
# UTF
    .e insert 0 abc\u4e4e\u0153def
    .e insert 0 abc乎œdef
    list [.e index 3] [.e index 4] [.e index end]
} -cleanup {
    destroy .e
} -result {3 4 8}
test entry-3.36 {EntryWidgetCmd procedure, "insert" widget command} -setup {
    entry .e
} -body {
1442
1443
1444
1445
1446
1447
1448
1449

1450
1451
1452
1453
1454
1455
1456
1447
1448
1449
1450
1451
1452
1453

1454
1455
1456
1457
1458
1459
1460
1461







-
+







} -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 integer but got "gorp"}
} -returnCodes error -result {expected floating-point number but got "gorp"}
test entry-3.73 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
1529
1530
1531
1532
1533
1534
1535
1536

1537
1538
1539
1540
1541
1542
1543
1534
1535
1536
1537
1538
1539
1540

1541
1542
1543
1544
1545
1546
1547
1548







-
+







    pack .e
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview 0
    update
    .e xview -4
    .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
1552
1553
1554
1555
1556
1557
1558
1559

1560
1561
1562
1563
1564
1565
1566
1557
1558
1559
1560
1561
1562
1563

1564
1565
1566
1567
1568
1569
1570
1571







-
+







} -result 73
test entry-3.86 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e insert 10 \u4e4e
    .e insert 10 
    update
# UTF
# If Tcl_NumUtfChars wasn't used, wrong answer would be:
# 0.106383 0.117021 0.117021
    set x {}
    .e xview moveto .1
    lappend x [format {%.6f} [lindex [.e xview] 0]]
1613
1614
1615
1616
1617
1618
1619
1620

1621
1622
1623
1624
1625
1626
1627
1618
1619
1620
1621
1622
1623
1624

1625
1626
1627
1628
1629
1630
1631
1632







-
+







} -result {abcde}
test entry-5.3 {ConfigureEntry procedure, -textvariable} -setup {
    unset -nocomplain x
    entry .e
} -body {
    .e insert 0 "Some text"
    .e configure -textvariable x
    return $x
    set x
} -cleanup {
    destroy .e
} -result {Some text}
test entry-5.4 {ConfigureEntry procedure, -textvariable} -setup {
    unset -nocomplain x
    entry .e
} -body {
1648
1649
1650
1651
1652
1653
1654
1655

1656
1657
1658
1659
1660
1661
1662
1653
1654
1655
1656
1657
1658
1659

1660
1661
1662
1663
1664
1665
1666
1667







-
+







    .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]
    return $x
    set x
} -cleanup {
    destroy .e1 .e2
} -result {{This is so} {This is so} 1234}
test entry-5.6 {ConfigureEntry procedure} -setup {
    entry .e
    pack .e
} -body {
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
1689
1690
1691
1692
1693
1694
1695
1696

1697

1698
1699
1700
1701
1702
1703
1704
1705
1706
1707

1708
1709
1710
1711
1712
1713
1714
1715







+
-
+
-

+








-
+








test entry-5.7 {ConfigureEntry procedure} -setup {
    entry .e -font {Helvetica -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Courier -12} -width 4 -xscrollcommand scroll
    .e insert end "01234567890"
    update idletasks
    set timeout [after 500 {set $scrollInfo "timeout"}]
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    vwait scrollInfo
    .e configure -width 5
    vwait scrollInfo
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.000000 0.363636}


test entry-5.8 {ConfigureEntry procedure} -constraints {
    fonts
    fonts failsOnXQuarz
} -setup {
    entry .e -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e configure -width 0 -font {Helvetica -12}
    .e insert end "0123"
    update
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
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







+


-














+


-







test entry-7.1 {InsertChars procedure} -setup {
    unset -nocomplain contents
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 abcde
    .e insert 2 XXX
    set timeout [after 500 {set $scrollInfo "timeout"}]
    vwait scrollInfo
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abXXXcde abXXXcde {0.000000 1.000000}}

test entry-7.2 {InsertChars procedure} -setup {
    unset -nocomplain contents
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 abcde
    .e insert 500 XXX
    set timeout [after 500 {set $scrollInfo "timeout"}]
    vwait scrollInfo
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abcdeXXX abcdeXXX {0.000000 1.000000}}
test entry-7.3 {InsertChars procedure} -setup {
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
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







+


-













+

-
+
-













+


-







test entry-8.1 {DeleteChars procedure} -setup {
    unset -nocomplain contents
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 abcde
    .e delete 2 4
    set timeout [after 500 {set $scrollInfo "timeout"}]
    vwait scrollInfo
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abe abe {0.000000 1.000000}}
test entry-8.2 {DeleteChars procedure} -setup {
    unset -nocomplain contents
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 abcde
    .e delete -2 2
    .e delete -1 2
    set timeout [after 500 {set $scrollInfo "timeout"}]
    vwait scrollInfo
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {cde cde {0.000000 1.000000}}
test entry-8.3 {DeleteChars procedure} -setup {
    unset -nocomplain contents
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 abcde
    .e delete 3 1000
    set timeout [after 500 {set $scrollInfo "timeout"}]
    vwait scrollInfo
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abc abc {0.000000 1.000000}}
test entry-8.4 {DeleteChars procedure} -setup {
2322
2323
2324
2325
2326
2327
2328
2329

2330
2331
2332
2333
2334
2335
2336
2328
2329
2330
2331
2332
2333
2334

2335
2336
2337
2338
2339
2340
2341
2342







-
+







    .e xview 4
    .e delete 4 6
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 4
test entry-8.18 {DeleteChars procedure} -setup {
test entry-8.18 {DeleteChars procedure} -constraints failsOnUbuntuNoXft -setup {
    entry .e -width 0 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 "xyzzy"
    update
    .e delete 2 4
2829
2830
2831
2832
2833
2834
2835
2836

2837
2838
2839
2840
2841
2842
2843
2835
2836
2837
2838
2839
2840
2841

2842
2843
2844
2845
2846
2847
2848
2849







-
+







test entry-13.23 {GetEntryIndex procedure} -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index -10
    .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
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
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







+
+


-









+


-









+


-












-
+

+
+







    destroy .e
} -result {0.000000 1.000000}


test entry-17.1 {EntryUpdateScrollbar procedure} -body {
    entry .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e delete 0 end
    .e insert 0 123
    set timeout [after 500 {set $scrollInfo "timeout"}]
    vwait scrollInfo
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.000000 1.000000}
test entry-17.2 {EntryUpdateScrollbar procedure} -body {
    entry .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 0123456789abcdef
    .e xview 3
    set timeout [after 500 {set $scrollInfo "timeout"}]
    vwait scrollInfo
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.187500 0.812500}
test entry-17.3 {EntryUpdateScrollbar procedure} -body {
    entry .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 abcdefghijklmnopqrs
    .e xview 6
    set timeout [after 500 {set $scrollInfo "timeout"}]
    vwait scrollInfo
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.315789 0.842105}
test entry-17.4 {EntryUpdateScrollbar procedure} -setup {
    proc bgerror msg {
	global x
	set x $msg
}
} -body {
    entry .e -width 5 -xscrollcommand thisisnotacommand
    entry .e -width 5
    pack .e
    update idletasks
    .e configure -xscrollcommand thisisnotacommand
    vwait x
    list $x $errorInfo
} -cleanup {
    destroy .e
    rename bgerror {}
} -result {{invalid command name "thisisnotacommand"} {invalid command name "thisisnotacommand"
    while executing
3043
3044
3045
3046
3047
3048
3049
3050

3051
3052
3053
3054
3055
3056
3057
3052
3053
3054
3055
3056
3057
3058

3059
3060
3061
3062
3063
3064
3065
3066







-
+







    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 a
    return $::vVals
    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 {
3075
3076
3077
3078
3079
3080
3081
3082

3083
3084
3085
3086
3087
3088
3089
3084
3085
3086
3087
3088
3089
3090

3091
3092
3093
3094
3095
3096
3097
3098







-
+







        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 ab   ;# previous settings
    .e insert end c
    return $::vVals
    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 {
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
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







-
+
















-
+
















-
+


















-
+




















-
+

















-
+




















-
+

















-
+


















-
+


















-
+







        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 a123bc   ;# previous settings
    .e delete 2
    return $::vVals
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e 0 2 a13bc a123bc 2 all key}

test entry-19.6 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 a13bc   ;# previous settings
    .e configure -validate key
    .e delete 1 3
    return $::vVals
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e 0 1 abc a13bc 13 key key}

test entry-19.7 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focus \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abc                 ;# previous settings
    set ::vVals {}
    .e insert end d
    return $::vVals
    set ::vVals
} -cleanup {
    destroy .e
} -result {}

test entry-19.8 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e configure -validate focus    ;# previous settings
    .e insert end abcd              ;# previous settings
    focus -force .e
# update necessary to process FocusIn event
    update
    return $::vVals
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} focus focusin}

test entry-19.9 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focus \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd      ;# previous settings
    focus -force .e         ;# previous settings
    update                  ;# previous settings
# update necessary to process FocusIn event
    focus -force .
# update necessary to process FocusOut event
    update
    return $::vVals
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} focus focusout}

test entry-19.10 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd          ;# previous settings
    focus -force .e
# update necessary to process FocusIn event
    update
    return $::vVals
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} all focusin}

test entry-19.11 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd          ;# previous settings
    focus -force .e             ;# previous settings
# update necessary to process FocusIn event
    update                      ;# previous settings
    focus -force .
# update necessary to process FocusOut event
    update
    return $::vVals
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} all focusout}

test entry-19.12 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focusin \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 abcd              ;# previous settings
    focus -force .e
# update necessary to process FocusIn event
    update
    return $::vVals
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} focusin focusin}

test entry-19.13 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focusin \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd              ;# previous settings
    set ::vVals {}
    focus -force .
# update necessary to process FocusOut event
    update
    return $::vVals
    set ::vVals
} -cleanup {
    destroy .e
} -result {}

test entry-19.14 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focuso \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd              ;# previous settings
    set ::vVals {}                  ;# previous settings
    focus -force .e
# update necessary to process FocusIn event
    update
    return $::vVals
    set ::vVals
} -cleanup {
    destroy .e
} -result {}

test entry-19.15 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
3298
3299
3300
3301
3302
3303
3304
3305

3306
3307
3308
3309
3310
3311
3312
3307
3308
3309
3310
3311
3312
3313

3314
3315
3316
3317
3318
3319
3320
3321







-
+







    set ::vVals {}                  ;# previous settings
    focus -force .e                 ;# previous settings
# update necessary to process FocusIn event
    update                          ;# previous settings
    focus -force .
# update necessary to process FocusOut event
    update
    return $::vVals
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} focusout focusout}

# the same as 19.16 but added [.e validate] to returned list
test entry-19.16 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
3381
3382
3383
3384
3385
3386
3387
3388

3389
3390
3391
3392
3393
3394
3395
3390
3391
3392
3393
3394
3395
3396

3397
3398
3399
3400
3401
3402
3403
3404







-
+







    set ::e nextdata                 ;# previous settings

    .e configure -validatecommand [list doval2 %W %d %i %P %s %S %v %V]
    .e validate
    list [.e cget -validate] [.e get] $::vVals
} -cleanup {
    destroy .e
} -result {none mydata {.e -1 -1 nextdata nextdata {} all forced}}
} -result {none nextdata {.e -1 -1 nextdata nextdata {} all forced}}

## This leaves validate alone because we trigger validation through the
## textvar (a write trace), and the write during validation triggers
## nothing (by definition of avoiding loops on var traces).  This is
## one of those "dangerous" conditions where the user will have a
## different value in the entry widget shown as is in the textvar.
test entry-19.20 {entry widget validation} -setup {
3407
3408
3409
3410
3411
3412
3413




















3414
3415
3416
3417
3418
3419
3420
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







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








    .e configure -validate all
    set ::e testdata
    list [.e cget -validate] [.e get] $::e $::vVals
} -cleanup {
    destroy .e
} -result {all testdata mydata {.e -1 -1 testdata mydata {} all forced}}

## This leaves validate alone because we trigger validation through the
## textvar (a write trace), and the write during validation triggers
## nothing (by definition of avoiding loops on var traces).  This is
## one of those "dangerous" conditions where the user will have a
## different value in the entry widget shown as is in the textvar.
test entry-19.21 {entry widget validation - bug 40e4bf6198} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate key \
        -validatecommand [list doval2 %W %d %i %P %s %S %v %V] \
        -textvariable ::e
    pack .e
    set ::e origdata
    .e insert 0 A
    list [.e cget -validate] [.e get] $::e $::vVals
} -cleanup {
    destroy .e
} -result {none origdata mydata {.e 1 0 Aorigdata origdata A key key}}

##
## End validation tests
##

test entry-20.1 {widget deletion while active} -body {
    entry .e -validate all \
	    -validatecommand { destroy %W ; return 1 } \
3473
3474
3475
3476
3477
3478
3479
3480

3481
3482
3483
3484
3485
3486
3487
3502
3503
3504
3505
3506
3507
3508

3509
3510
3511
3512
3513
3514
3515
3516







-
+







    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

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
1
2
3



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



23























24









25






26










27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44


45
46
47
48
49
50
51
52
53



-
-
-
+
+
+
















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










+







-
-
+
+







# This file is a Tcl script to test the code in tkEvent.c.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 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

    # Characters with meaning to Tcl...
    for {set i $start} {$i <= $finish} {incr i} {
        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
    }

    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
    }

    # Most punctuation
    array set keypress_lookup {
    array set keypress_lookup [list \
        ! exclam
        % percent
        & ampersand
        ( parenleft
        ) parenright
        * asterisk
        + plus
        , comma
        - minus
	    -    minus \
        . period
        / slash
        : colon
        < less
        = equal
        > greater
	    >    greater \
        ? question
        @ at
        ^ asciicircum
        _ underscore
        | bar
        ~ asciitilde
        ' apostrophe
    }
    # Characters with meaning to Tcl...
    array set keypress_lookup [list \
	    \"   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]} {

Changes to tests/filebox.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




-
-
+
+


-
+







# This file is a Tcl script to test out Tk's "tk_getOpenFile" and
# "tk_getSaveFile" commands. It is organized in the standard fashion
# for Tcl tests.
#
# Copyright (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.1
package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

test fileDialog-0.1 {GetFileName: file types: MakeFilter() fails} {
    # MacOS type that is too long

    set res [list [catch {tk_getSaveFile -filetypes {{"foo" .foo {\0\0\0\0\0}}}} msg] $msg]

Changes to tests/focus.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




-
-
+
+






+
+
+







# This file is a Tcl script to test out the "focus" command and the
# other procedures in the file tkFocus.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 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(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} {
	    button .t.$i -text .t.$i -relief raised -bd 2
304
305
306
307
308
309
310
311

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

324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344

345
346
347
348
349
350
351
307
308
309
310
311
312
313

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

326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346

347
348
349
350
351
352
353
354







-
+











-
+




















-
+







    list $focusInfo [focus]
} -result {{out . NotifyNonlinear
in .t NotifyNonlinearVirtual
in .t.b1 NotifyNonlinear
} .t.b1}

test focus-2.6 {TkFocusFilterEvent procedure, FocusIn events} -constraints {
    unix  testwrapper
    unix  testwrapper failsOnUbuntu failsOnXQuarz
} -body {
    focus .t.b1
    focus .
    update
    event gen [testwrapper .t] <FocusIn> -detail NotifyAncestor
    set focusInfo {}
    set x [focus]
    event gen . <x>
    list $x $focusInfo
} -result {.t.b1 {press .t.b1 x}}
test focus-2.7 {TkFocusFilterEvent procedure, FocusOut events} -constraints {
    unix  testwrapper
    unix  testwrapper failsOnUbuntu failsOnXQuarz
} -body {
    set result {}
    foreach detail {NotifyAncestor NotifyInferior NotifyNonlinear
	    NotifyNonlinearVirtual NotifyPointer NotifyPointerRoot
	    NotifyVirtual} {
	    focus -force .t.b1
	    event gen [testwrapper .t] <FocusOut> -detail $detail
	    update
	    lappend result [focus]
    }
    return $result
} -result {{} .t.b1 {} {} .t.b1 .t.b1 {}}
test focus-2.8 {TkFocusFilterEvent procedure, FocusOut events} -constraints {
    unix  testwrapper
} -body {
    focus -force .t.b1
    event gen .t.b1 <FocusOut> -detail NotifyAncestor
    focus
} -result {.t.b1}
test focus-2.9 {TkFocusFilterEvent procedure, FocusOut events} -constraints {
    unix  testwrapper
    unix  testwrapper failsOnUbuntu failsOnXQuarz
} -body {
    focus .t.b1
    event gen [testwrapper .] <FocusOut> -detail NotifyAncestor
    focus
} -result {}
test focus-2.10 {TkFocusFilterEvent procedure, Enter events} -constraints {
    unix  testwrapper
595
596
597
598
599
600
601
602

603
604
605
606
607
608
609
598
599
600
601
602
603
604

605
606
607
608
609
610
611
612







-
+









# I don't know how to test most of the remaining procedures of this file
# explicitly;  they've already been exercised by the preceding tests.

# Test 5.1 fails (before and after update)
test focus-5.1 {ChangeXFocus procedure, don't take focus unless have it} -constraints {
    unix testwrapper secureserver
    unix testwrapper secureserver failsOnUbuntu failsOnXQuarz
} -body {
    setupbg
    focusSetup
    focus -force .t
    update
    set result [focus]
    send [dobg {tk appname}] {focus -force .; update}

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 (c) 1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1995 Sun Microsystems, Inc.
# Copyright © 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
1
2
3
4


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




-
-
+
+










+
+







# This file is a Tcl script to test out Tk's "font" command
# plus the procedures in tkFont.c.  It is organized in the
# standard white-box fashion for Tcl tests.
#
# Copyright (c) 1996-1998 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1996-1998 Sun Microsystems, Inc.
# Copyright © 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(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] {
57
58
59
60
61
62
63
64
65
66



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






86
87
88
89
90
91
92
93
94



95
96
97
98

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117

118
119
120
121

122
123
124
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148
149
150
151
152

153
154
155

156
157
158
159
160
161

162
163
164
165
166
167
168
59
60
61
62
63
64
65



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






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



94
95
96
97
98
99

100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

119
120
121
122

123
124
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140
141

142
143
144
145
146
147
148
149
150
151
152
153

154
155
156

157
158
159
160
161
162

163
164
165
166
167
168
169
170







-
-
-
+
+
+













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






-
-
-
+
+
+



-
+


















-
+



-
+









-
+








-
+











-
+


-
+





-
+









test font-1.1 {TkFontPkgInit} -setup {
    catch {interp delete foo}
} -body {
    interp create foo
    foo eval {
		load {} Tk
		wm geometry . +0+0
		update
	load {} Tk
	wm geometry . +0+0
	update
    }
    interp delete foo
} -result {}


test font-2.1 {TkFontPkgFree} -setup {
    catch {interp delete foo}
    set x {}
} -body {
    interp create foo

    # Makes sure that named font was visible only to child interp.
    foo eval {
		load {} Tk
		wm geometry . +0+0
		button .b -font {times 16} -text "hi"
		pack .b
		font create wiggles -family courier -underline 1
		update
	load {} Tk
	wm geometry . +0+0
	button .b -font {times 16} -text "hi"
	pack .b
	font create wiggles -family courier -underline 1
	update
    }
    lappend x [catch {font configure wiggles} msg; set msg]

    # Tests cancelling the idle handler for TheWorldHasChanged,
    # because app goes away before idle serviced.
    foo eval {
		.b config -font wiggles
		font config wiggles -size 24
		destroy .
	.b config -font wiggles
	font config wiggles -size 24
	destroy .
    }
    lappend x [foo eval {catch {font families} msg; set msg}]
} -cleanup {
        interp delete foo
    interp delete foo
} -result {{named font "wiggles" doesn't exist} {can't invoke "font" command: application has been destroyed}}


test font-3.1 {font command: general} -body {
    font
} -returnCodes error -result {wrong # args: should be "font option ?arg?"}
test font-3.2 {font command: general} -body {
    font xyz
} -returnCodes error -result {bad option "xyz": must be actual, configure, create, delete, families, measure, metrics, or names}


test font-4.1 {font command: actual: arguments} -body {
    # (skip < 0)
    font actual xyz -displayof
} -returnCodes error -result {value for "-displayof" missing}
test font-4.2 {font command: actual: arguments} -body {
    # (objc < 3)
    font actual
} -returnCodes error -result {wrong # args: should be "font actual font ?-displayof window? ?option? ?--? ?char?"}
} -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} -body {
test font-4.9 {font command: actual} -constraints {unix noExceed failsOnUbuntu} -body {
    # (objc > 3) so objPtr = objv[3 + skip]
    string tolower [font actual {-family times} -family]
} -result {times}
test font-4.10 {font command: actual} -constraints win -body {
    # (objc > 3) so objPtr = objv[3 + skip]
    font actual {-family times} -family
} -result {times}
test font-4.11 {font command: bad option} -body {
    font actual xyz -style
} -returnCodes error -result {bad option "-style": must be -family, -size, -weight, -slant, -underline, or -overstrike}
test font-4.12 {font command: actual} -body {
    font actual {-family times} -- \ud800
    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 {
    font actual {-family times} -family -- \uD800\uDC00
} -result {times}
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}


test font-5.1 {font command: configure} -body {
190
191
192
193
194
195
196
197

198
199
200
201
202
203
204
205

206
207

208
209
210
211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
226

227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246

247
248
249
250
251
252
253
192
193
194
195
196
197
198

199
200
201
202
203
204
205
206

207
208

209
210
211
212
213
214
215
216
217
218
219

220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247

248
249
250
251
252
253
254
255







-
+







-
+

-
+










-
+







-
+



















-
+







test font-5.4 {font command: configure: get all options} -setup {
    catch {font delete xyz}
} -body {
    # (objc == 3) so objPtr = NULL
    font create xyz -family xyz
    lindex [font configure xyz] 1
} -cleanup {
	font delete xyz
    font delete xyz
} -result xyz
test font-5.5 {font command: configure: get one option} -setup {
    clearnondefaultfonts
} -body {
    # (objc == 4) so objPtr = objv[3]
    font create xyz -family xyz
    font configure xyz -family
	getnondefaultfonts
    getnondefaultfonts
} -cleanup {
	font delete xyz
    font delete xyz
} -result xyz
test font-5.6 {font command: configure: update existing font} -setup {
    catch {font delete xyz}
} -body {
    # else result = ConfigAttributesObj()
    font create xyz
    font configure xyz -family xyz
    update
    font configure xyz -family
} -cleanup {
	font delete xyz
    font delete xyz
} -result xyz
test font-5.7 {font command: configure: bad option} -setup {
    catch {font delete xyz}
} -body {
    font create xyz
    font configure xyz -style
} -cleanup {
	font delete xyz
    font delete xyz
} -returnCodes error -result {bad option "-style": must be -family, -size, -weight, -slant, -underline, or -overstrike}


test font-6.1 {font command: create: make up name} -setup {
    clearnondefaultfonts
} -body {
    # (objc < 3) so name = NULL
    font create
    getnondefaultfonts
} -cleanup {
    font delete font1
} -result {font1}
test font-6.2 {font command: create: name specified} -setup {
    clearnondefaultfonts
} -body {
    # not (objc < 3)
    font create xyz
    getnondefaultfonts
} -cleanup {
	font delete xyz
    font delete xyz
} -result {xyz}
test font-6.3 {font command: create: name not really specified} -setup {
    clearnondefaultfonts
} -body {
    # (name[0] == '-') so name = NULL
    font create -family xyz
    getnondefaultfonts
281
282
283
284
285
286
287
288

289
290
291
292
293
294
295
296
297

298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313

314
315
316
317
318
319
320
283
284
285
286
287
288
289

290
291
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314

315
316
317
318
319
320
321
322







-
+








-
+















-
+







test font-6.7 {font command: create: already exists} -setup {
    catch {font delete xyz}
} -body {
    # (CreateNamedFont() != TCL_OK)
    font create xyz
    font create xyz
} -cleanup {
	font delete xyz
    font delete xyz
} -returnCodes error -result {named font "xyz" already exists}

test font-7.1 {font command: delete: arguments} -body {
    # (objc < 3)
    font delete
} -returnCodes error -result {wrong # args: should be "font delete fontname ?fontname ...?"}
test font-7.2 {font command: delete: loop test} -setup {
    clearnondefaultfonts
	set x {}
    set x {}
} -body {
    # for (i = 2; i < objc; i++)
    font create a -underline 1
    font create b -underline 1
    font create c -underline 1
    font create d -underline 1
    font create e -underline 1
    lappend x [lsort [getnondefaultfonts]]
    font delete a e c b
    lappend x [lsort [getnondefaultfonts]]
} -cleanup {
    getnondefaultfonts
} -result {{a b c d e} d}
test font-7.3 {font command: delete: loop test} -setup {
    clearnondefaultfonts
	set x {}
    set x {}
} -body {
    # (namedHashPtr == NULL) in middle of loop
    font create a -underline 1
    font create b -underline 1
    font create c -underline 1
    font create d -underline 1
    font create e -underline 1
339
340
341
342
343
344
345
346

347
348
349
350
351
352
353
354
355
356
357
358
359
360

361
362
363
364
365
366
367
341
342
343
344
345
346
347

348
349
350
351
352
353
354
355
356
357
358
359
360
361

362
363
364
365
366
367
368
369







-
+













-
+







    # (nfPtr->refCount != 0)
    font create xyz
    .t.f configure -font xyz
    font delete xyz
    font actual xyz
    font configure xyz
} -cleanup {
	destroy .t.f
    destroy .t.f
} -returnCodes error -result {named font "xyz" doesn't exist}
test font-7.6 {font command: delete: mark for later deletion} -setup {
    destroy .t.f
    catch {font delete xyz}
    pack [label .t.f]
    update
} -body {
    # (nfPtr->refCount != 0)
    font create xyz
    .t.f configure -font xyz
    font delete xyz
    font actual xyz
    catch {font configure xyz}
	.t.f cget -font
    .t.f cget -font
} -cleanup {
	destroy .t.f
} -result xyz
test font-7.7 {font command: delete: actually delete} -setup {
    catch {font delete xyz}
} -body {
    # not (nfPtr->refCount != 0)
379
380
381
382
383
384
385
386

387
388
389
390
391
392
393
381
382
383
384
385
386
387

388
389
390
391
392
393
394
395







-
+







    # (objc - skip != 2) when skip == 0
    font families xyz
} -returnCodes error -result {wrong # args: should be "font families ?-displayof window?"}
test font-8.3 {font command: families: arguments} -body {
    # (objc - skip != 2) when skip == 2
    font families -displayof . xyz
} -returnCodes error -result {wrong # args: should be "font families ?-displayof window?"}
test font-8.4 {font command: families} -body {
test font-8.4 {font command: families} -constraints failsOnUbuntu -body {
    # TkpGetFontFamilies()
    regexp -nocase times [font families]
} -result 1


test font-9.1 {font command: measure: arguments} -body {
    # (skip < 0)
426
427
428
429
430
431
432
433

434
435
436
437

438
439
440
441
442
443
444
428
429
430
431
432
433
434

435
436
437
438

439
440
441
442
443
444
445
446







-
+



-
+







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"
511
512
513
514
515
516
517
518

519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537

538
539
540
541
542
543
544

545
546
547
548
549
550
551

552
553
554
555
556
557
558
559
560

561
562
563
564
565
566
567
568
569

570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585


586
587
588
589
590
591
592
593
594

595
596
597
598
599
600
601
602
603
604
605
606
607

608
609
610
611
612
613
614
615
616
617
618
619
620
621
622

623
624
625
626
627
628
629
513
514
515
516
517
518
519

520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538

539
540
541
542
543
544
545

546
547
548
549
550
551
552

553
554
555
556
557
558
559
560
561

562
563
564
565
566
567
568
569
570

571
572
573
574
575
576
577
578
579
580
581
582
583
584
585


586
587
588
589
590
591
592
593
594
595

596
597
598
599
600
601
602
603
604
605
606
607
608

609
610
611
612
613
614
615
616
617
618
619
620
621
622
623

624
625
626
627
628
629
630
631







-
+


















-
+






-
+






-
+








-
+








-
+














-
-
+
+








-
+












-
+














-
+







test font-12.1 {UpdateDependantFonts procedure: no users} -setup {
    catch {font delete xyz}
} -body {
    # (nfPtr->refCount == 0)
    font create xyz
    font configure xyz -family times
} -cleanup {
	font delete xyz
    font delete xyz
} -result {}
test font-12.2 {UpdateDependantFonts procedure: pings the widgets} -setup {
    destroy .t.f
    catch {font delete xyz}
    pack [label .t.f]
    update
} -body {
    font create xyz -family times -size 20
    .t.f config -font xyz -text "abcd" -padx 0 -bd 0 -highlightthickness 0
    set a1 [font measure xyz "abcd"]
    update
    set b1 [winfo reqwidth .t.f]
    font configure xyz -family helvetica -size 20
    set a2 [font measure xyz "abcd"]
    update
    set b2 [winfo reqwidth .t.f]
    expr {$a1==$b1 && $a2==$b2}
} -cleanup {
	destroy .t.f
    destroy .t.f
    font delete xyz
} -result 1


test font-13.1 {CreateNamedFont: new named font} -setup {
    catch {font delete xyz}
	set x {}
    set x {}
} -body {
    # not (new == 0)
    lappend x [getnondefaultfonts]
    font create xyz
    lappend x [getnondefaultfonts]
} -cleanup {
	font delete xyz
    font delete xyz
} -result {{} xyz}
test font-13.2 {CreateNamedFont: named font already exists} -setup {
    catch {font delete xyz}
} -body {
    # (new == 0)
    font create xyz
    font create xyz
} -cleanup {
	font delete xyz
    font delete xyz
} -returnCodes error -result {named font "xyz" already exists}
test font-13.3 {CreateNamedFont: named font already exists} -setup {
    catch {font delete xyz}
} -body {
    # (nfPtr->deletePending == 0)
    font create xyz
    font create xyz
} -cleanup {
	font delete xyz
    font delete xyz
} -returnCodes error -result {named font "xyz" already exists}
test font-13.4 {CreateNamedFont: recreate "deleted" font} -setup {
    destroy .t.f
    catch {font delete xyz}
    pack [label .t.f]
    update
} -body {
    # not (nfPtr->deletePending == 0)
    font create xyz -family times
    .t.f configure -font xyz
    font delete xyz
    font create xyz -family courier
    font configure xyz -family
} -cleanup {
	font delete xyz
	destroy .t.f
    font delete xyz
    destroy .t.f
} -result {courier}


test font-14.1 {Tk_GetFont procedure} -body {
} -result {}


test font-15.1 {Tk_AllocFontFromObj - converting internal reps} -constraints {
	testfont
    testfont
} -setup {
    destroy .b1 .b2
} -body {
    set x {Times 16}
    lindex $x 0
    button .b1 -font $x
    lindex $x 0
    testfont counts {Times 16}
} -cleanup {
    destroy .b1 .b2
} -result {{1 0}}
test font-15.2 {Tk_AllocFontFromObj - discard stale font} -constraints {
	testfont
    testfont
} -setup {
    destroy .b1 .b2
    set result {}
} -body {
    set x {Times 16}
    button .b1 -font $x
    destroy .b1
    lappend result [testfont counts {Times 16}]
    button .b2 -font $x
    lappend result [testfont counts {Times 16}]
} -cleanup {
    destroy .b2
} -result {{} {{1 1}}}
test font-15.3 {Tk_AllocFontFromObj - reuse existing font} -constraints {
	testfont
    testfont
} -setup {
    destroy .b1 .b2
    set result {}
} -body {
    set x {Times 16}
    button .b1 -font $x
    lappend result [testfont counts {Times 16}]
638
639
640
641
642
643
644
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
640
641
642
643
644
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







-
+











-
+










-
+







    pack [label .t.f]
    update
} -body {
    # (new == 0)
    .t.f config -font {-family fixed}
    lindex [font actual {-family fixed}] 0
} -cleanup {
	destroy .t.f
    destroy .t.f
} -result {-family}
test font-15.5 {Tk_AllocFontFromObj procedure: get named font} -setup {
    destroy .t.f
    catch {font delete xyz}
    pack [label .t.f]
    update
} -body {
    # (namedHashPtr != NULL)
    font create xyz
    .t.f config -font xyz
} -cleanup {
	destroy .t.f
    destroy .t.f
    font delete xyz
} -result {}
test font-15.6 {Tk_AllocFontFromObj procedure: not a named font} -setup {
    destroy .t.f
    pack [label .t.f]
    update
} -body {
    # not (namedHashPtr != NULL)
    .t.f config -font {times 20}
} -cleanup {
	destroy .t.f
    destroy .t.f
} -result {-family} -result {}
test font-15.7 {Tk_AllocFontFromObj procedure: get native font} -constraints {
	unix
} -setup {
    destroy .t.f
    pack [label .t.f]
    update
705
706
707
708
709
710
711
712

713
714
715
716
717
718
719
720
721

722
723
724
725
726
727
728
729
730
731
732

733
734
735
736
737
738
739
740
741
742
743
744

745
746
747
748
749
750
751
707
708
709
710
711
712
713

714
715
716
717
718
719
720
721
722

723
724
725
726
727
728
729
730
731
732
733

734
735
736
737
738
739
740
741
742
743
744
745

746
747
748
749
750
751
752
753







-
+








-
+










-
+











-
+







    font actual "\{xyz"
} -returnCodes error -result "font \"{xyz\" doesn't exist"
test font-15.11 {Tk_AllocFontFromObj procedure: get attribute font} -body {
    # not (ParseFontNameObj() != TCL_OK)
    lindex [font actual {plan 9}] 0
} -result {-family}
test font-15.12 {Tk_AllocFontFromObj procedure: setup tab width} -setup {
	destroy .l
    destroy .l
} -body {
    # Tk_MeasureChars(fontPtr, "0", ...)
    label .l -bd 0 -padx 0  -highlightthickness 0 -font $fixed -text "a\tb"
    update
    set res1 [winfo reqwidth .l]
	set res2 [expr [font measure $fixed "0"]*9]
	expr {$res1 eq $res2}
} -cleanup {
	destroy .l
    destroy .l
} -result 1
test font-15.13 {Tk_AllocFontFromObj procedure: underline position} -setup {
    destroy .t.f
    pack [label .t.f]
    update
} -body {
    # (fontPtr->underlineHeight == 0) because size was < 10
    .t.f config -text "underline" -font "times -8 underline"
    update
} -cleanup {
	destroy .t.f
    destroy .t.f
} -result {}


test font-16.1 {Tk_NameOfFont procedure} -setup {
    destroy .t.f
    pack [label .t.f]
    update
} -body {
    .t.f config -font -family\ fixed
    .t.f cget -font
} -cleanup {
	destroy .t.f
    destroy .t.f
} -result {-family fixed}


test font-17.1 {Tk_FreeFontFromObj - reference counts} -constraints {
	testfont
} -setup {
    destroy .b1 .b2 .b3
923
924
925
926
927
928
929
930

931
932
933
934
935
936
937
925
926
927
928
929
930
931

932
933
934
935
936
937
938
939







-
+







    if {[string match lucida*bright $x]} {
		psfontname "{lucida bright} 10"
    } else {
		set x {LucidaBright}
    }
} -result {LucidaBright}
test font-21.6 {Tk_PostscriptFontName procedure: spaces} -constraints {
	x11
	x11 failsOnUbuntu
} -body {
    psfontname "{new century schoolbook} 10"
} -result {NewCenturySchlbk-Roman}

test font-21.7 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix
} -body {
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
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







-
+

-
-
-
-
+
+
+
+


-
+




-
+







-
+
















-
-
-
+
+
+



-
-
-
+
+
+



-
-
-
+
+
+



-
-
-
+
+
+








-
-
-
+
+
+



-
-
-
+
+
+




-
+

-
+

-
+

-
+







-
+

-
+

-
-
-
+
+
+







-
-
-
+
+
+

-
-
-
+
+
+







-
-
-
+
+
+

-
-
-
+
+
+






-
-
-
+
+
+



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





-
-
-
-
-
+
+
+
+
+











-
+











-
+
















-
+







    win
} -body {
    set x [psfontname {{times new roman} 12 italic bold}]
} -result {Times-BoldItalic}


test font-22.1 {Tk_TextWidth procedure} -setup {
	destroy .t.l
    destroy .t.l
} -body {
	label .t.l -padx 0 -pady 0 -bd 0 -highlightthickness 0 -justify left \
		-text "0" -font "Courier -12"
	pack .t.l
	set ax [winfo reqwidth .t.l]
    label .t.l -padx 0 -pady 0 -bd 0 -highlightthickness 0 -justify left \
	    -text "0" -font "Courier -12"
    pack .t.l
    set ax [winfo reqwidth .t.l]
    expr {[font measure [.t.l cget -font] "000"] eq $ax*3}
} -cleanup {
	destroy .t.l
    destroy .t.l
} -result 1


test font-23.1 {Tk_UnderlineChars procedure} -setup {
	destroy .t.t
    destroy .t.t
} -body {
    text .t.t
    .t.t insert 1.0 abc\tdefg
    .t.t tag config sel -underline 1
    .t.t tag add sel 1.0 end
    update
} -cleanup {
	destroy .t.t
    destroy .t.t
} -result {}


# Data used in 24.* tests
destroy .t.l
label .t.l -padx 0 -pady 0 -bd 0 -highlightthickness 0 -justify left \
	-text "0" -font "Courier -12"
pack .t.l
update
set ax [winfo reqwidth .t.l]
set ay [winfo reqheight .t.l]
test font-24.1 {Tk_ComputeTextLayout: empty string} -body {
    .t.l config -text ""
} -result {}
test font-24.2 {Tk_ComputeTextLayout: simple string} -body {
    .t.l config -text "000"
	update
	list [expr {[winfo reqwidth .t.l] eq [expr {$ax * 3}]}] \
		[expr {[winfo reqheight .t.l] eq $ay}]
    update
    list [expr {[winfo reqwidth .t.l] eq [expr {$ax * 3}]}] \
	    [expr {[winfo reqheight .t.l] eq $ay}]
} -result {1 1}
test font-24.3 {Tk_ComputeTextLayout: find special chars} -body {
    .t.l config -text "000\n000"
	update
	list [expr {[winfo reqwidth .t.l] eq [expr {$ax * 3}]}] \
		[expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
    update
    list [expr {[winfo reqwidth .t.l] eq [expr {$ax * 3}]}] \
	    [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
} -result {1 1}
test font-24.4 {Tk_ComputeTextLayout: calls Tk_MeasureChars} -body {
    .t.l config -text "000\n000"
	update
	list [expr {[winfo reqwidth .t.l] eq [expr {$ax * 3}]}] \
		[expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
    update
    list [expr {[winfo reqwidth .t.l] eq [expr {$ax * 3}]}] \
	    [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
} -result {1 1}
test font-24.5 {Tk_ComputeTextLayout: break line} -body {
    .t.l config -text "000\t00000" -wrap [expr 9 * $ax]
	update
	list [expr {[winfo reqwidth .t.l] eq [expr {$ax * 8}]}] \
		[expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
    update
    list [expr {[winfo reqwidth .t.l] eq [expr {$ax * 8}]}] \
	    [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
} -cleanup {
    .t.l config -wrap 0
} -result {1 1}
test font-24.6 {Tk_ComputeTextLayout: normal ended on special char} -body {
    .t.l config -text "000\n000"
} -result {}
test font-24.7 {Tk_ComputeTextLayout: special char was \n} -body {
    .t.l config -text "000\n0000"
	update
	list [expr {[winfo reqwidth .t.l] eq [expr {$ax * 4}]}] \
		[expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
    update
    list [expr {[winfo reqwidth .t.l] eq [expr {$ax * 4}]}] \
	    [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
} -result {1 1}
test font-24.8 {Tk_ComputeTextLayout: special char was \t} -body {
    .t.l config -text "000\t00"
	update
	list [expr {[winfo reqwidth .t.l] eq [expr {$ax * 10}]}] \
		[expr {[winfo reqheight .t.l] eq $ay}]
    update
    list [expr {[winfo reqwidth .t.l] eq [expr {$ax * 10}]}] \
	    [expr {[winfo reqheight .t.l] eq $ay}]
} -result {1 1}
test font-24.9 {Tk_ComputeTextLayout: tab didn't cause break} -body {
    set x {}
    .t.l config -text "000\t000"
	update
    update
    lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 11}]}]
	lappend x [expr {[winfo reqheight .t.l] eq $ay}]
    lappend x [expr {[winfo reqheight .t.l] eq $ay}]
    .t.l config -text "000\t000" -wrap [expr 100 * $ax]
	update
    update
    lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 11}]}]
	lappend x [expr {[winfo reqheight .t.l] eq $ay}]
    lappend x [expr {[winfo reqheight .t.l] eq $ay}]
    return $x
} -cleanup {
    .t.l config -wrap 0
} -result {1 1 1 1}
test font-24.10 {Tk_ComputeTextLayout: tab caused break} -body {
    set x {}
    .t.l config -text "000\t"
	update
    update
    lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 8}]}]
	lappend x [expr {[winfo reqheight .t.l] eq $ay}]
    lappend x [expr {[winfo reqheight .t.l] eq $ay}]
    .t.l config -text "000\t00" -wrap [expr $ax * 6]
	update
	lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 8}]}]
	lappend x [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
    update
    lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 8}]}]
    lappend x [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
    return $x
} -cleanup {
    .t.l config -wrap 0
} -result {1 1 1 1}
test font-24.11 {Tk_ComputeTextLayout: absorb spaces at eol} -body {
    set x {}
    .t.l config -text "000            000" -wrap [expr {$ax * 5}]
	update
	lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 3}]}]
	lappend x [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
    update
    lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 3}]}]
    lappend x [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
    .t.l config -text "000            "
	update
	lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 3}]}]
	lappend x [expr {[winfo reqheight .t.l] eq $ay}]
    update
    lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 3}]}]
    lappend x [expr {[winfo reqheight .t.l] eq $ay}]
    return $x
} -cleanup {
    .t.l config -wrap 0
} -result {1 1 1 1}
test font-24.12 {Tk_ComputeTextLayout: append non-printing spaces to chunk} -body {
    set x {}
    .t.l config -text "000            0000" -wrap [expr {$ax * 5}]
	update
	lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 4}]}]
	lappend x [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
    update
    lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 4}]}]
    lappend x [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
    .t.l config -text "000\t00            0000" -wrap [expr {$ax * 12}]
	update
	lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 10}]}]
	lappend x [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
    update
    lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 10}]}]
    lappend x [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
    return $x
} -cleanup {
    .t.l config -wrap 0
} -result {1 1 1 1}
test font-24.13 {Tk_ComputeTextLayout: many lines -> realloc line array} -body {
    .t.l config -text "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
	update
	list [expr {[winfo reqwidth .t.l] eq 1}] \
		[expr {[winfo reqheight .t.l] eq [expr {$ay * 129}]}]
    update
    list [expr {[winfo reqwidth .t.l] eq 1}] \
	    [expr {[winfo reqheight .t.l] eq [expr {$ay * 129}]}]
} -result {1 1}
test font-24.14 {Tk_ComputeTextLayout: text ended with \n} -body {
    set x {}
	.t.l config -text "0000"
	update
	lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 4}]}]
	lappend x [expr {[winfo reqheight .t.l] eq $ay}]
	.t.l config -text "0000\n"
	update
	lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 4}]}]
	lappend x [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
    return $x
    .t.l config -text "0000"
    update
    lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 4}]}]
    lappend x [expr {[winfo reqheight .t.l] eq $ay}]
    .t.l config -text "0000\n"
    update
    lappend x [expr {[winfo reqwidth .t.l] eq [expr {$ax * 4}]}]
    lappend x [expr {[winfo reqheight .t.l] eq [expr {$ay * 2}]}]
    set x
} -result {1 1 1 1}
destroy .t.l

test font-24.15 {Tk_ComputeTextLayout: justification} -setup {
    set x {}
	destroy .t.c
	canvas .t.c -closeenough 0
	.t.c create text 0 0 -tags text -anchor nw -just left -font "Courier -12"
	pack .t.c
	update
    destroy .t.c
    canvas .t.c -closeenough 0
    .t.c create text 0 0 -tags text -anchor nw -just left -font "Courier -12"
    pack .t.c
    update
} -body {
    csetup "000\n00000"
    .t.c itemconfig text -just left
    lappend x [.t.c index text @[expr $ax*2],0]
    .t.c itemconfig text -just center
    lappend x [.t.c index text @[expr $ax*2],0]
    .t.c itemconfig text -just right
    lappend x [.t.c index text @[expr $ax*2],0]
    .t.c itemconfig text -just left
    return $x
} -cleanup {
	destroy .t.c
    destroy .t.c
} -result {2 1 0}


test font-25.1 {Tk_FreeTextLayout procedure} -setup {
    destroy .t.f
    pack [label .t.f]
    update
} -body {
    .t.f config -text foo
    .t.f config -text boo
} -cleanup {
	destroy .t.f
    destroy .t.f
} -result {}


# Canvas created for tests: 26.*
destroy .t.c
canvas .t.c -closeenough 0
.t.c create text 0 0 -tags text -anchor nw -just left -font "Courier -12"
pack .t.c
update
test font-26.1 {Tk_DrawTextLayout procedure: auto-detect last char} -setup {
    destroy .t.f
    pack [label .t.f]
    update
} -body {
    .t.f config -text foo
} -cleanup {
	destroy .t.f
    destroy .t.f
} -result {}
test font-26.2 {Tk_DrawTextLayout procedure: multiple chunks} -body {
    csetup "000\t00\n000"
} -result {}
test font-26.3 {Tk_DrawTextLayout: draw subset of chunk: numDisplay <= 0} -body {
    csetup "000\t00"
    .t.c select from text 3
1677
1678
1679
1680
1681
1682
1683
1684

1685
1686
1687
1688
1689
1690
1691

1692
1693
1694
1695
1696
1697
1698
1679
1680
1681
1682
1683
1684
1685

1686
1687
1688
1689
1690
1691
1692

1693
1694
1695
1696
1697
1698
1699
1700







-
+






-
+







destroy .t.c

#  Label used in 27.* tests
destroy .t.f
pack [label .t.f]
update
test font-27.1 {Tk_UnderlineTextLayout procedure: no underline chosen} -body {
    .t.f config -text "foo" -under -1
    .t.f config -text "foo" -underline -1
} -result {}
test font-27.2 {Tk_UnderlineTextLayout procedure: underline not visible} -body {
    .t.f config -text "000          00000" -wrap [expr $ax*7] -under 10
} -result {}
test font-27.3 {Tk_UnderlineTextLayout procedure: underline is visible} -body {
    .t.f config -text "000          00000" -wrap [expr $ax*7] -under 5
    .t.f config -wrap -1 -under -1
    .t.f config -wrap -1 -underline -1
} -result {}
destroy .t.f



# Canvas created for tests: 28.*
destroy .t.c
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
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







-
+





-
+



-
+





-
+



-
+





-
+



-
+





-
+



-
+





-
+




-
+






-
+




-
+





-
+



-
+





-
+



-
+





-
+



-
+





-
+



-
+









-
+










-
+





-
+







destroy .t.c
canvas .t.c -closeenough 0
.t.c create text 0 0 -tags text -anchor nw -just left -font "Courier -12"
pack .t.c
update
test font-30.1 {Tk_DistanceToTextLayout procedure: loop once} -body {
    csetup "000\n000\n000"
	.t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x 0 -y 0
    return $x
} -cleanup {
	bind all <Enter> {}
    bind all <Enter> {}
} -result 0
test font-30.2 {Tk_DistanceToTextLayout procedure: loop multiple} -body {
    csetup "000\n000\n000"
	.t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x $ax -y $ay
    return $x
} -cleanup {
	bind all <Enter> {}
    bind all <Enter> {}
} -result 5
test font-30.3 {Tk_DistanceToTextLayout procedure: loop to end} -body {
    csetup "000\n0\n000"
	.t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x [expr $ax*2] -y $ay
    return $x
} -cleanup {
	bind all <Enter> {}
    bind all <Enter> {}
} -result {}
test font-30.4 {Tk_DistanceToTextLayout procedure: hit a special char (tab)} -body {
    csetup "000\t000\n000"
	.t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x [expr $ax*6] -y 0
    return $x
} -cleanup {
	bind all <Enter> {}
    bind all <Enter> {}
} -result 3
test font-30.5 {Tk_DistanceToTextLayout procedure: ignore newline} -body {
    csetup "000\n0\n000"
	.t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x [expr $ax*2] -y $ay
    return $x
} -cleanup {
	bind all <Enter> {}
    bind all <Enter> {}
} -result {}
test font-30.6 {Tk_DistanceToTextLayout procedure: ignore spaces at eol} -body {
    csetup "000\n000      000000000"
    .t.c itemconfig text -width [expr $ax*10]
	.t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x [expr $ax*5] -y $ay
    .t.c itemconfig text -width 0
    return $x
} -cleanup {
	bind all <Enter> {}
    bind all <Enter> {}
} -result {}
.t.c itemconfig text -justify center
test font-30.7 {Tk_DistanceToTextLayout procedure: on left side} -body {
    csetup "0\n000"
	.t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x 0 -y 0
    return $x
} -cleanup {
	bind all <Enter> {}
    bind all <Enter> {}
} -result {}
test font-30.8 {Tk_DistanceToTextLayout procedure: on right side} -body {
    csetup "0\n000"
	.t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x [expr $ax*2] -y 0
    return $x
} -cleanup {
	bind all <Enter> {}
    bind all <Enter> {}
} -result {}
test font-30.9 {Tk_DistanceToTextLayout procedure: inside line} -body {
    csetup "0\n000"
	.t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x $ax -y 0
    return $x
} -cleanup {
	bind all <Enter> {}
    bind all <Enter> {}
} -result 0
test font-30.10 {Tk_DistanceToTextLayout procedure: above line} -body {
    csetup "0\n000"
	.t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x 0 -y 0
    return $x
} -cleanup {
	bind all <Enter> {}
    bind all <Enter> {}
} -result {}
test font-30.11 {Tk_DistanceToTextLayout procedure: below line} -body {
    csetup "000\n0"
	.t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x 0 -y $ay
    return $x
} -cleanup {
	bind all <Enter> {}
} -result {}
test font-30.12 {Tk_DistanceToTextLayout procedure: in line} -body {
    csetup "0\n000"
	.t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x $ax -y $ay
    return $x
} -cleanup {
	bind all <Enter> {}
} -result 3
.t.c itemconfig text -justify left
test font-30.13 {Tk_DistanceToTextLayout procedure: exact hit} -body {
    csetup "000"
	.t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    .t.c bind all <Enter> {lappend x [.t.c index current @%x,%y]}
    set x {}
    event generate .t.c <Leave>
    event generate .t.c <Enter> -x $ax -y 0
    return $x
} -cleanup {
	bind all <Enter> {}
    bind all <Enter> {}
} -result 1
destroy .t.c


# Canvas created for tests 31.*
destroy .t.c
canvas .t.c -closeenough 0
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
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







-
-
-
-
-
+
+
+
+
+












-
+







    # so it's enough to check with a small rectangle with small negative y coords.
    .t.c find overlapping 5 -7 7 -5
} -result 1
destroy .t.c


test font-32.1 {Tk_TextLayoutToPostscript: ensure buffer doesn't overflow} -setup {
	destroy .t.c
	canvas .t.c -closeenough 0
	.t.c create text 0 0 -tags text -anchor nw -just left -font "Courier -12"
	pack .t.c
	update
    destroy .t.c
    canvas .t.c -closeenough 0
    .t.c create text 0 0 -tags text -anchor nw -just left -font "Courier -12"
    pack .t.c
    update
} -body {
    # If there were a whole bunch of returns or tabs in a row, then the
    # temporary buffer could overflow and write on the stack.
    csetup "qwertyuiopasdfghjklzxcvbnm1234qwertyuiopasdfghjklzxcvbnm\n"
    .t.c itemconfig text -width 800
    .t.c insert text end "qwertyuiopasdfghjklzxcvbnm1234qwertyuiopasdfghjklzxcvbnm\n"
    .t.c insert text end "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
    .t.c insert text end "end"
    set x [.t.c postscript]
    set i [string first "(qwerty" $x]
    string range $x $i [expr {$i + 278}]
} -cleanup {
	destroy .t.c
    destroy .t.c
} -result {(qwertyuiopasdfghjklzxcvbnm1234qwertyuiopasdfghjklzxcvbnm)]
[(qwertyuiopasdfghjklzxcvbnm1234qwertyuiopasdfghjklzxcvbnm)]
[()]
[()]
[()]
[()]
[()]
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
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







-
+

-
-
-
-
+
+
+
+





-
+

-
-
-
-
+
+
+
+

-
+



-
+

-
-
-
-
+
+
+
+

-
+



-
+

-
-
-
-
+
+
+
+

-
+



-
+

-
-
-
-
+
+
+
+

-
+



-
+

-
-
-
-
+
+
+
+

-
+



-
+


-
+


-
+


-
+


-
+










-
+










-
+












-
+




-
-
+
+

-
+



-
+

-
-
+
+

-
+



-
+

-
-
+
+

-
+



-
+

-
-
+
+

-
+



-
+

-
-
+
+

-
+



-
+

-
-
+
+

-
+







} -body {
    # (objc & 1)
    font create xyz -family
} -returnCodes error -result {value for "-family" option missing}

test font-34.3 {ConfigAttributesObj procedure: family} -setup {
    catch {font delete xyz}
	set x {}
    set x {}
} -body {
	font create xyz -family xyz
	lappend x [font config xyz -family]
	font config xyz -family times
	lappend x [font config xyz -family]
    font create xyz -family xyz
    lappend x [font config xyz -family]
    font config xyz -family times
    lappend x [font config xyz -family]
} -cleanup {
	font delete xyz
} -result {xyz times}
test font-34.4 {ConfigAttributesObj procedure: size} -setup {
    catch {font delete xyz}
	set x {}
    set x {}
} -body {
	font create xyz -size 20
	lappend x [font config xyz -size]
	font config xyz -size 40
	lappend x [font config xyz -size]
    font create xyz -size 20
    lappend x [font config xyz -size]
    font config xyz -size 40
    lappend x [font config xyz -size]
} -cleanup {
	font delete xyz
    font delete xyz
} -result {20 40}
test font-34.5 {ConfigAttributesObj procedure: weight} -setup {
    catch {font delete xyz}
	set x {}
    set x {}
} -body {
	font create xyz -weight normal
	lappend x [font config xyz -weight]
	font config xyz -weight bold
	lappend x [font config xyz -weight]
    font create xyz -weight normal
    lappend x [font config xyz -weight]
    font config xyz -weight bold
    lappend x [font config xyz -weight]
} -cleanup {
	font delete xyz
    font delete xyz
} -result {normal bold}
test font-34.6 {ConfigAttributesObj procedure: slant} -setup {
    catch {font delete xyz}
	set x {}
    set x {}
} -body {
	font create xyz -slant roman
	lappend x [font config xyz -slant]
	font config xyz -slant italic
	lappend x [font config xyz -slant]
    font create xyz -slant roman
    lappend x [font config xyz -slant]
    font config xyz -slant italic
    lappend x [font config xyz -slant]
} -cleanup {
	font delete xyz
    font delete xyz
} -result {roman italic}
test font-34.7 {ConfigAttributesObj procedure: underline} -setup {
    catch {font delete xyz}
	set x {}
    set x {}
} -body {
	font create xyz -underline 0
	lappend x [font config xyz -underline]
	font config xyz -underline 1
	lappend x [font config xyz -underline]
    font create xyz -underline 0
    lappend x [font config xyz -underline]
    font config xyz -underline 1
    lappend x [font config xyz -underline]
} -cleanup {
	font delete xyz
    font delete xyz
} -result {0 1}
test font-34.8 {ConfigAttributesObj procedure: overstrike} -setup {
    catch {font delete xyz}
	set x {}
    set x {}
} -body {
	font create xyz -overstrike 0
	lappend x [font config xyz -overstrike]
	font config xyz -overstrike 1
	lappend x [font config xyz -overstrike]
    font create xyz -overstrike 0
    lappend x [font config xyz -overstrike]
    font config xyz -overstrike 1
    lappend x [font config xyz -overstrike]
} -cleanup {
	font delete xyz
    font delete xyz
} -result {0 1}

test font-34.9 {ConfigAttributesObj procedure: size} -body {
	font create xyz -size xyz
    font create xyz -size xyz
} -returnCodes error -result {expected integer but got "xyz"}
test font-34.10 {ConfigAttributesObj procedure: weight} -body {
	font create xyz -weight xyz
    font create xyz -weight xyz
} -returnCodes error -result {bad -weight value "xyz": must be normal, or bold}
test font-34.11 {ConfigAttributesObj procedure: slant} -body {
	font create xyz -slant xyz
    font create xyz -slant xyz
} -returnCodes error -result {bad -slant value "xyz": must be roman, or italic}
test font-34.12 {ConfigAttributesObj procedure: underline} -body {
	font create xyz -underline xyz
    font create xyz -underline xyz
} -returnCodes error -result {expected boolean value but got "xyz"}
test font-34.13 {ConfigAttributesObj procedure: overstrike} -body {
	font create xyz -overstrike xyz
    font create xyz -overstrike xyz
} -returnCodes error -result {expected boolean value but got "xyz"}


test font-35.1 {GetAttributeInfoObj procedure: one attribute} -setup {
    catch {font delete xyz}
} -body {
    # (objPtr != NULL)
    font create xyz -family xyz
    font config xyz -family
} -cleanup {
	font delete xyz
    font delete xyz
} -result {xyz}


test font-36.1 {GetAttributeInfoObj procedure: unknown attribute} -setup {
    catch {font delete xyz}
} -body {
    # (Tcl_GetIndexFromObj() != TCL_OK)
    font create xyz
    font config xyz -xyz
} -cleanup {
	font delete xyz
    font delete xyz
} -returnCodes {
    error
} -result {bad option "-xyz": must be -family, -size, -weight, -slant, -underline, or -overstrike}


test font-37.1 {GetAttributeInfoObj procedure: all attributes} -setup {
    catch {font delete xyz}
} -body {
    # not (objPtr != NULL)
    font create xyz -family xyz
    font config xyz
} -cleanup {
	font delete xyz
    font delete xyz
} -result {-family xyz -size 0 -weight normal -slant roman -underline 0 -overstrike 0}
test font-37.2 {GetAttributeInfo procedure: family} -setup {
    catch {font delete xyz}
} -body {
	font create xyz -family xyz
	font config xyz -family
    font create xyz -family xyz
    font config xyz -family
} -cleanup {
	font delete xyz
    font delete xyz
} -result {xyz}
test font-37.3 {GetAttributeInfo procedure: size} -setup {
    catch {font delete xyz}
	set x {}
    set x {}
} -body {
	font create xyz -size 20
	font config xyz -size
    font create xyz -size 20
    font config xyz -size
} -cleanup {
	font delete xyz
    font delete xyz
} -result 20
test font-37.4 {GetAttributeInfo procedure: weight} -setup {
    catch {font delete xyz}
	set x {}
    set x {}
} -body {
	font create xyz -weight normal
	font config xyz -weight
    font create xyz -weight normal
    font config xyz -weight
} -cleanup {
	font delete xyz
    font delete xyz
} -result {normal}
test font-37.5 {GetAttributeInfo procedure: slant} -setup {
    catch {font delete xyz}
	set x {}
    set x {}
} -body {
	font create xyz -slant italic
	font config xyz -slant
    font create xyz -slant italic
    font config xyz -slant
} -cleanup {
	font delete xyz
    font delete xyz
} -result {italic}
test font-37.6 {GetAttributeInfo procedure: underline} -setup {
    catch {font delete xyz}
	set x {}
    set x {}
} -body {
	font create xyz -underline yes
	font config xyz -underline
    font create xyz -underline yes
    font config xyz -underline
} -cleanup {
	font delete xyz
    font delete xyz
} -result 1
test font-37.7 {GetAttributeInfo procedure: overstrike} -setup {
    catch {font delete xyz}
	set x {}
    set x {}
} -body {
	font create xyz -overstrike no
	font config xyz -overstrike
    font create xyz -overstrike no
    font config xyz -overstrike
} -cleanup {
	font delete xyz
    font delete xyz
} -result 0


# In tests below, one field is set to "xyz" so that font name doesn't
# look like a native X font, so that ParseFontNameObj or TkParseXLFD will
# be called.

2252
2253
2254
2255
2256
2257
2258
2259

2260
2261
2262
2263
2264
2265
2266
2254
2255
2256
2257
2258
2259
2260

2261
2262
2263
2264
2265
2266
2267
2268







-
+







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
	unixOrWin failsOnUbuntuNoXft
} -body {
    lrange [font actual {times 12 bold italic overstrike underline}] 4 end
} -result {-weight bold -slant italic -underline 1 -overstrike 1}
test font-38.12 {ParseFontNameObj procedure: stylelist error} -body {
    font actual {times 12 bold xyz}
} -returnCodes error -result {unknown font style "xyz"}
test font-38.13 "ParseFontNameObj: options with hyphenated family: bug #2791352" -body {
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
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







-
-
+
+

-
+


-
+

-
-
+
+

-
+


-
+









-
+











-
+




-
+







    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} -setup {
	set oldscale [tk scaling]
test font-44.1 {TkFontGetPixels: size < 0} -constraints failsOnUbuntu -setup {
    set oldscale [tk scaling]
} -body {
	tk scaling 0.5
    tk scaling 0.5
    font actual {times -12} -size
} -cleanup {
	tk scaling $oldscale
    tk scaling $oldscale
} -result 24
test font-44.2 {TkFontGetPoints: size >= 0} -constraints noExceed -setup {
	set oldscale [tk scaling]
test font-44.2 {TkFontGetPoints: size >= 0} -constraints {noExceed failsOnUbuntuNoXft} -setup {
    set oldscale [tk scaling]
} -body {
	tk scaling 0.5
    tk scaling 0.5
    font actual {times 12} -size
} -cleanup {
	tk scaling $oldscale
    tk scaling $oldscale
} -result 12


test font-45.1 {TkFontGetAliasList: no match} -body {
    font actual {snarky 10} -family
} -result [font actual {-size 10} -family]
test font-45.2 {TkFontGetAliasList: match} -constraints win -body {
    font actual {times 10} -family
} -result {times}
test font-45.3 {TkFontGetAliasList: match} -constraints {noExceed} -body {
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
    } else {
        set res [expr {[font actual {{times new roman} 10} -family] eq \
                       [font actual {times 10} -family]} ]
    }
} -result 1


test font-46.1 {font actual, with character, no option, no --} -body {
	font actual {times 10} a
    font actual {times 10} a
} -match glob -result [list -family [font actual {times 10} -family] -size *\
		 -slant roman -underline 0 -overstrike 0]

test font-46.2 {font actual, with character introduced by --} -body {
	font actual {times 10} -- -
    font actual {times 10} -- -
} -match glob -result [list -family [font actual {times 10} -family] -size *\
		 -slant roman -underline 0 -overstrike 0]

test font-46.3 {font actual, with character and option} -body {
    font actual {times 10} -family a
} -result [font actual {times 10} -family]

Changes to tests/fontchooser.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
17
18
19
20
21


-
+

-
+



+
+
+


-
+







# Test the "tk::fontchooser" command
#
# Copyright (c) 2008 Pat Thoyts
# Copyright © 2008 Pat Thoyts

package require tcltest 2.1
package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint 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} {
105
106
107
108
109
110
111
112

113
114
115
116
117
118
119
120

121
122
123
124
125
126
127
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130







-
+







-
+







    }
    set x
} -result {Hello}

test fontchooser-2.1 {fontchooser -title (cyrillic)} -constraints scriptImpl -body {
    start {
        tk::fontchooser::Configure \
            -title "\u041f\u0440\u0438\u0432\u0435\u0442"
            -title "Привет"
        tk::fontchooser::Show
    }
    then {
        set x [wm title $::tk_dialog]
        Click cancel
    }
    set x
} -result "\u041f\u0440\u0438\u0432\u0435\u0442"
} -result "Привет"

test fontchooser-3.0 {fontchooser -parent} -constraints scriptImpl -body {
    start {
        tk::fontchooser::Configure -parent .
        tk::fontchooser::Show
    }
    then {
175
176
177
178
179
180
181
182

183
184
185
186
187
188
189
190
191






192
193
194
195
196
197
198
199
200
201
178
179
180
181
182
183
184

185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210







-
+









+
+
+
+
+
+










    }
    then {
        Click ok
    }
    expr {$::testfont ne {}}
} -result 1

test fontchooser-4.4 {fontchooser -font} -constraints scriptImpl -body {
test fontchooser-4.4 {fontchooser -font} -constraints {scriptImpl failsOnUbuntuNoXft} -body {
    start {
        tk::fontchooser::Configure -command ApplyFont -font {times 14 bold}
        tk::fontchooser::Show
    }
    then {
        Click ok
    }
    lrange $::testfont 1 end
} -result {14 bold}

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
1
2
3
4



5
6
7
8
9
10
11
12
13
14




-
-
-
+
+
+







# This file is a Tcl script to test out the "frame", "labelframe" and
# "toplevel" commands of Tk.  It is organized in the standard fashion for Tcl
# tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

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 (c) 1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 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 (c) 1998 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1998 Sun Microsystems, Inc.
# Copyright © 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/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 (c) 1998-2000 by Ajuba Solutions.
# Copyright © 1998-2000 Ajuba Solutions.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

103
104
105
106
107
108
109
110

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

110
111
112
113
114
115
116
117







-
+







    set curr [grab current .]
    if { [string length $curr] > 0 } {
	grab release $curr
    }
    grab status .
} -cleanup {
    grab release .
} -result {none}
} -result none
test grab-2.2 {Tk_GrabObjCmd, grab status gives correct status} -body {
    set curr [grab current .]
    if { [string length $curr] > 0 } {
	grab release $curr
    }
    grab .
    grab status .

Changes to tests/grid.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 *NEW* "grid" command of Tk. It is
# (almost) organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

41
42
43
44
45
46
47
48

49
50
51
52
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, forget, info, location, propagate, remove, rowconfigure, size, or slaves}
} -returnCodes error -result {bad option "foo": must be anchor, bbox, columnconfigure, configure, content, forget, info, location, propagate, remove, rowconfigure, or size}
test grid-1.3 {basic argument checking} -body {
    button .b
    grid .b -row 0 -column
} -cleanup {
    grid_reset 1.3
} -returnCodes error -result {extra option or option with no value}
test grid-1.4 {basic argument checking} -body {
    button .b
    grid configure .b - foo
} -cleanup {
    grid_reset 1.4
} -returnCodes error -result {unexpected parameter "foo" in configure list: should be window name or option}
test grid-1.5 {basic argument checking} -body {
    grid .
} -returnCodes error -result {can't manage ".": it's a top-level window}
test grid-1.6 {basic argument checking} -body {
    grid x
} -returnCodes error -result {can't determine master window}
} -returnCodes error -result {can't determine container window}
test grid-1.7 {basic argument checking} -body {
    grid configure x
} -returnCodes error -result {can't determine master window}
} -returnCodes error -result {can't determine container window}
test grid-1.8 {basic argument checking} -body {
    button .b
    grid x .b
} -cleanup {
    grid_reset 1.8
} -returnCodes ok -result {}
test grid-1.9 {basic argument checking} -body {
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 master ?column row ?column row??"}
} -returnCodes error -result {wrong # args: should be "grid bbox window ?column row ?column row??"}
test grid-2.4 {bbox} -body {
    grid bbox .bad 0 0
} -returnCodes error -result {bad window path name ".bad"}
test grid-2.5 {bbox} -body {
    grid bbox . x 0
} -returnCodes error -result {expected integer but got "x"}
test grid-2.6 {bbox} -body {
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
141
142
143
144
145
146
147

148
149
150
151
152
153
154
155







-
+








test grid-3.1 {configure: basic argument checking} -body {
    grid configure foo
} -returnCodes error -result {bad argument "foo": must be name of window}
test grid-3.2 {configure: basic argument checking} -body {
    button .b
    grid configure .b
    grid slaves .
    grid content .
} -cleanup {
    grid_reset 3.2
} -result {.b}
test grid-3.3 {configure: basic argument checking} -body {
    button .b
    grid .b -row -1
} -cleanup {
175
176
177
178
179
180
181
182

183
184
185
186

187
188
189
190
191
192
193
194
195
196

197
198
199
200
201
202
203
204
205
206
207
208
209

210
211
212
213
214
215
216
217
218
219

220
221
222
223
224
225
226
227

228
229

230
231
232
233
234
235
236
175
176
177
178
179
180
181

182
183
184
185

186
187
188
189
190
191
192
193
194
195

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

209
210
211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
226

227
228

229
230
231
232
233
234
235
236







-
+



-
+









-
+












-
+









-
+







-
+

-
+







} -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 slaves .
    grid content .
} -cleanup {
    grid_reset 3.8
} -result {.b}
test grid-3.9 {configure: basic argument checking} -body {
    button .b
    grid configure y .b
} -cleanup {
    grid_reset 3.9
} -returnCodes error -result {invalid window shortcut, "y" should be '-', 'x', or '^'}
test grid-3.10 {ConfigureSlave procedure, bad -in option} -body {
test grid-3.10 {ConfigureContent procedure, bad -in option} -body {
    frame .f
    grid .f -in .f
} -cleanup {
    grid_reset 3.10
} -returnCodes error -result {window can't be managed in itself}
test grid-3.11 {prevent management loops} -body {
    frame .f1
    frame .f2
    grid .f1 -in .f2
    grid .f2 -in .f1
} -cleanup {
    grid_reset 3.11
} -returnCodes error -result {can't put .f2 inside .f1, would cause management loop}
} -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]
    set a [grid slaves .]
    set a [grid content .]
    grid forget .b .c
    lappend a [grid slaves .]
    lappend a [grid content .]
    return $a
} -cleanup {
    grid_reset 4.2
} -result {.b {}}
test grid-4.3 {forget} -body {
    button .c
    grid .c -row 2 -column 2 -rowspan 2 -columnspan 2 -padx 3 -pady 4 -sticky ns
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 master x y"}
} -returnCodes error -result {wrong # args: should be "grid location window x y"}
test grid-6.2 {location: basic argument checking} -body {
    grid location .bad 0 0
} -returnCodes error -result {bad window path name ".bad"}
test grid-6.3 {location: basic argument checking} -body {
    grid location . x y
} -returnCodes error -result {bad screen distance "x"}
test grid-6.4 {location: basic argument checking} -body {
512
513
514
515
516
517
518
519
520


521
522
523


524
525
526
527
528
529





530
531
532


533
534
535


536
537
538


539
540
541


542
543
544


545
546

547
548
549
550
551

552
553
554
555

556
557
558
559
560
561
562
563
564

565
566
567

568
569
570
571
572
573
574
575
576
577
578
579

580
581
582
583
584

585
586
587
588
589
590
591
512
513
514
515
516
517
518


519
520
521


522
523
524





525
526
527
528
529
530


531
532
533


534
535
536


537
538
539


540
541
542


543
544
545

546
547
548
549
550

551
552
553
554

555
556
557
558
559
560
561
562
563

564
565
566

567
568
569
570
571
572
573
574
575
576
577
578

579
580
581
582
583

584
585
586
587
588
589
590
591







-
-
+
+

-
-
+
+

-
-
-
-
-
+
+
+
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
+




-
+



-
+








-
+


-
+











-
+




-
+







    update
    lappend a [grid size .]
    return $a
} -cleanup {
    grid_reset 8.6
} -result {{51 11} {51 11} {31 11} {21 11} {16 1} {1 1}}

test grid-9.1 {slaves} -body {
    grid slaves .
test grid-9.1 {content} -body {
    grid content .
} -returnCodes ok -result {}
test grid-9.2 {slaves} -body {
    grid slaves .foo
test grid-9.2 {content} -body {
    grid content .foo
} -returnCodes error -result {bad window path name ".foo"}
test grid-9.3 {slaves} -body {
    grid slaves a b
} -returnCodes error -result {wrong # args: should be "grid slaves window ?-option value ...?"}
test grid-9.4 {slaves} -body {
    grid slaves . a b
test grid-9.3 {content} -body {
    grid content a b
} -returnCodes error -result {wrong # args: should be "grid content window ?-option value ...?"}
test grid-9.4 {content} -body {
    grid content . a b
} -returnCodes error -result {bad option "a": must be -column or -row}
test grid-9.5 {slaves} -body {
    grid slaves . -column x
test grid-9.5 {content} -body {
    grid content . -column x
} -returnCodes error -result {expected integer but got "x"}
test grid-9.6 {slaves} -body {
    grid slaves . -row -3
test grid-9.6 {content} -body {
    grid content . -row -3
} -returnCodes error -result {-3 is an invalid value: should NOT be < 0}
test grid-9.7 {slaves} -body {
    grid slaves . -foo 3
test grid-9.7 {content} -body {
    grid content . -foo 3
} -returnCodes error -result {bad option "-foo": must be -column or -row}
test grid-9.8 {slaves} -body {
    grid slaves .x -row 3
test grid-9.8 {content} -body {
    grid content .x -row 3
} -returnCodes error -result {bad window path name ".x"}
test grid-9.9 {slaves} -body {
    grid slaves . -row 3
test grid-9.9 {content} -body {
    grid content . -row 3
} -returnCodes ok -result {}
test grid-9.10 {slaves} -body {
test grid-9.10 {content} -body {
    foreach i {0 1 2} {
	label .$i -text $i
	grid .$i -row $i -column $i
    }
    grid slaves .
    grid content .
} -cleanup {
    grid_reset 9.10
} -result {.2 .1 .0}
test grid-9.11 {slaves} -body {
test grid-9.11 {content} -body {
    catch {unset a}
    foreach i {0 1 2} {
	label .$i -text $i
	label .$i-x -text $i-x
	grid .$i -row $i -column $i
	grid .$i-x -row $i -column [incr i]
    }
    foreach row {0 1 2 3} {
	lappend a $row{[grid slaves . -row $row]}
	lappend a $row{[grid content . -row $row]}
    }
    foreach col {0 1 2 3} {
	lappend a $col{[grid slaves . -column $col]}
	lappend a $col{[grid content . -column $col]}
    }
    return $a
} -cleanup {
    grid_reset 9.11
} -result {{0{.0-x .0}} {1{.1-x .1}} {2{.2-x .2}} 3{} 0{.0} {1{.1 .0-x}} {2{.2 .1-x}} 3{.2-x}}

# column/row configure
test grid-10.1 {column/row configure} -body {
    grid columnconfigure .
} -cleanup {
    grid_reset 10.1
} -returnCodes error -result {wrong # args: should be "grid columnconfigure master index ?-option value ...?"}
} -returnCodes error -result {wrong # args: should be "grid columnconfigure window index ?-option value ...?"}
test grid-10.2 {column/row configure} -body {
    grid columnconfigure . 0 -weight 0 -pad
} -cleanup {
    grid_reset 10.2
} -returnCodes error -result {wrong # args: should be "grid columnconfigure master index ?-option value ...?"}
} -returnCodes error -result {wrong # args: should be "grid columnconfigure window index ?-option value ...?"}
test grid-10.3 {column/row configure} -body {
    grid columnconfigure .f 0 -weight
} -cleanup {
    grid_reset 10.3
} -returnCodes error -result {bad window path name ".f"}
test grid-10.4 {column/row configure} -body {
    grid columnconfigure . nine -weight
852
853
854
855
856
857
858
859

860
861
862
863
864
865

866
867
868
869
870
871
872
852
853
854
855
856
857
858

859
860
861
862
863
864

865
866
867
868
869
870
871
872







-
+





-
+







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 '^', cant find master}
} -returnCodes error -result {can't use '^', can't find container window}
test grid-11.2 {default widget placement} -body {
    button .b
    grid .b ^
} -cleanup {
    grid_reset 11.2
} -returnCodes error -result {can't find slave to extend with "^"}
} -returnCodes error -result {can't find content to extend with "^"}
test grid-11.3 {default widget placement} -body {
    button .b
    grid .b - - .c
} -cleanup {
    grid_reset 11.3
} -returnCodes error -result {bad window path name ".c"}
test grid-11.4 {default widget placement} -body {
913
914
915
916
917
918
919
920

921
922
923
924
925
926
927
913
914
915
916
917
918
919

920
921
922
923
924
925
926
927







-
+







} -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 slave to extend with "^"}
} -returnCodes error -result {can't find content to extend with "^"}
test grid-11.10 {default widget placement} -body {
    foreach i {1 2 3} {
	frame .f$i -width 100 -height 50 -highlightthickness 0 -bg red
    }
    grid .f1 .f2  -sticky nsew
    grid .f3   ^  -sticky nsew
    update
1158
1159
1160
1161
1162
1163
1164
1165

1166
1167
1168
1169
1170
1171
1172
1158
1159
1160
1161
1162
1163
1164

1165
1166
1167
1168
1169
1170
1171
1172







-
+







} -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}
1301
1302
1303
1304
1305
1306
1307
1308

1309
1310
1311

1312
1313
1314
1315
1316
1317
1318
1301
1302
1303
1304
1305
1306
1307

1308
1309
1310

1311
1312
1313
1314
1315
1316
1317
1318







-
+


-
+







    frame .1
    frame .2
    button .b
    grid .1 .2
    grid .b -in .1
    set a ""
    catch {unset info}; array set info [grid info .b]
    lappend a [grid slaves .1],[grid slaves .2],$info(-in)
    lappend a [grid content .1],[grid content .2],$info(-in)
    grid .b -in .2
    catch {unset info}; array set info [grid info .b]
    lappend a [grid slaves .1],[grid slaves .2],$info(-in)
    lappend a [grid content .1],[grid content .2],$info(-in)
    unset info
    return $a
} -cleanup {
    grid_reset 13.13
} -result {.b,,.1 ,.b,.2}

test grid-14.1 {structure notify} -body {
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
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







-
+


-
+

-
+

-
+



-
+




-
+

-
+

-
+







    update
    bind . <Configure> {}
    array get A
} -cleanup {
    grid_reset 14.3
} -result {.2 2 .0 1 . 2 .1 1}

test grid-15.1 {lost slave} -body {
test grid-15.1 {lost content} -body {
    button .b
    grid .b
    set a [grid slaves .]
    set a [grid content .]
    pack .b
    lappend a [grid slaves .]
    lappend a [grid content .]
    grid .b
    lappend a [grid slaves .]
    lappend a [grid content .]
} -cleanup {
    grid_reset 15.1
} -result {.b {} .b}
test grid-15.2 {lost slave} -body {
test grid-15.2 {lost content} -body {
    frame .f
    grid .f
    button .b
    grid .b -in .f
    set a [grid slaves .f]
    set a [grid content .f]
    pack .b -in .f
    lappend a [grid slaves .f]
    lappend a [grid content .f]
    grid .b -in .f
    lappend a [grid slaves .f]
    lappend a [grid content .f]
} -cleanup {
    grid_reset 15.2
} -result {.b {} .b}

test grid-16.1 {layout centering} -body {
    foreach i {0 1 2} {
	frame .$i -bg gray  -width 75 -height 50 -bd 2 -relief ridge
1970
1971
1972
1973
1974
1975
1976
1977

1978
1979

1980
1981
1982
1983
1984
1985
1986
1970
1971
1972
1973
1974
1975
1976

1977
1978

1979
1980
1981
1982
1983
1984
1985
1986







-
+

-
+








test grid-22.1 {remove: basic argument checking} {
    list [catch {grid remove foo} msg] $msg
} {1 {bad window path name "foo"}}
test grid-22.2 {remove} {
    button .c
    grid [button .b]
    set a [grid slaves .]
    set a [grid content .]
    grid remove .b .c
    lappend a [grid slaves .]
    lappend a [grid content .]
    return $a
} {.b {}}
grid_reset 22.2
test grid-22.3 {remove} {
    button .c
    grid .c -row 2 -column 2 -rowspan 2 -columnspan 2 -padx 3 -pady 4 -sticky ns
    grid remove .c
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
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







-
+















-
+







    # is ignored.
    destroy .a
    grid .c -row 0 -column 0
    grid info .c
} {-in . -column 0 -row 0 -columnspan 2 -rowspan 2 -ipadx 0 -ipady 0 -padx {3 5} -pady {4 7} -sticky ns}
grid_reset 22.5

test grid-23 {grid configure -in leaked from previous master - bug
test grid-23 {grid configure -in leaked from previous container window - bug
              6aea69fccbb266b7f0437686379fbe5b55442958} {
    frame .f
    frame .g
    pack .f .g
    text .t
    grid .t -in .f
    pack forget .f
    update
    grid .t -in .g
    # .t is now managed by .g; following lines must have no effect on .t
    pack .f
    update
    pack forget .f
    update
    winfo ismapped .t ; # must return 1
} {1}
} 1
grid_reset 23

test grid-24.1 {<<NoManagedChild>> fires on last grid forget} -setup {
    global A
    unset -nocomplain A
} -body {
    grid [frame .1]

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 (c) 1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

309
310
311
312
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
323
324
325







-
+
-
-

-
+









test image-6.1 {Tk_ImageCmd procedure, "types" option} -constraints {
    testImageType
} -body {
    image types x
} -returnCodes error -result {wrong # args: should be "image types"}
test image-6.2 {Tk_ImageCmd procedure, "types" option} -constraints {
test image-6.2 {Tk_ImageCmd procedure, "types" option} -body {
    testOldImageType
} -body {
    lsort [image types]
} -result {bitmap oldtest photo test}
} -match glob -result {bitmap*photo test}


test image-7.1 {Tk_ImageCmd procedure, "width" option} -body {
    image width
} -returnCodes error -result {wrong # args: should be "image width name"}
test image-7.2 {Tk_ImageCmd procedure, "width" option} -body {
    image width a b
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
353
354
355
356
357
358
359






360
361
362
363
364
365
366







-
-
-
-
-
-







    button .b -image myimage2
    lappend res [image inuse myimage2]
} -cleanup {
    imageCleanup
    catch {destroy .b}
} -result [list 0 1]

if {[tk windowingsystem] == "aqua" && $tcl_platform(osVersion) > 18} {
    # Aqua >= 10.14 will redraw the entire image in drawRect.
    set result_9_1 {{foo display 0 0 30 15}}
} else {
    set result_9_1 {{foo display 5 6 7 8}}
}
test image-9.1 {Tk_ImageChanged procedure} -constraints testImageType -setup {
    .c delete all
    imageCleanup
    update
} -body {
    image create test foo -variable x
    .c create image 50 50 -image foo
383
384
385
386
387
388
389
390

391
392
393
394
395
396

397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416

417
418
419
420
421
422
423
375
376
377
378
379
380
381

382






383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402

403
404
405
406
407
408
409
410







-
+
-
-
-
-
-
-
+



















-
+







        vwait x
    }
    after cancel $timer
    return $x
} -cleanup {
    .c delete all
    imageCleanup
} -result $result_9_1
} -result {{foo display 5 6 7 8}}
if {[tk windowingsystem] == "aqua" && $tcl_platform(osVersion) > 18} {
    # Aqua >= 10.14 will redraw the entire image.
    set result_9_2 {{foo display 0 0 30 15} {foo display 0 0 30 15}}
} else {
    set result_9_2 {{foo display 5 6 25 9} {foo display 0 0 12 14}}
}

test image-9.2 {Tk_ImageChanged procedure} -constraints testImageType -setup {
    .c delete all
    imageCleanup
    update
} -body {
    image create test foo -variable x
    .c create image 50 50 -image foo
    .c create image 90 100 -image foo
    update
    set x {}
    foo changed 5 6 7 8 30 15
    set timer [after 500 {lappend x "timed out"}]
    image create test myimage -variable x
    vwait x
    after cancel $timer
    return $x
} -cleanup {
    .c delete all
    imageCleanup
} -result $result_9_2
} -result {{foo display 5 6 25 9} {foo display 0 0 12 14}}

test image-10.1 {Tk_GetImage procedure} -setup {
    imageCleanup
} -body {
    .c create image 100 10 -image bad_name
} -cleanup {
    imageCleanup

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 (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit
133
134
135
136
137
138
139
140

141
142
143
144
145
146

147
148
149
150
151

152
153
154
155
156
157

158
159
160
161

162
163
164
165
166
167
168
169
170

171
172
173
174
175
176
177
178
179

180
181
182
183
184
185
186
133
134
135
136
137
138
139

140
141
142
143
144
145

146
147
148
149
150

151
152
153
154
155
156

157
158
159
160

161
162
163
164
165
166
167
168
169

170
171
172
173
174
175
176
177
178

179
180
181
182
183
184
185
186







-
+





-
+




-
+





-
+



-
+








-
+








-
+







	    [lindex [image1 configure -foreground] 4] \
	    [lindex [image1 configure -background] 4]
} -cleanup {
    image delete image1
} -result {image1 image1 0 0 #000000 {}}


test imageBmap-3.1 {ImgBmapConfigureMaster procedure, memory de-allocation} -body {
test imageBmap-3.1 {ImgBmapConfigureModel procedure, memory de-allocation} -body {
    image create bitmap i1 -data $data1
    i1 configure -data $data1
} -cleanup {
	image delete i1
} -result {}
test imageBmap-3.2 {ImgBmapConfigureMaster procedure} -body {
test imageBmap-3.2 {ImgBmapConfigureModel procedure} -body {
    image create bitmap i1 -data $data1
    list [catch {i1 configure -data bogus} msg] $msg [image width i1] \
	    [image height i1]
} -result {1 {format error in bitmap data} 16 16}
test imageBmap-3.3 {ImgBmapConfigureMaster procedure, memory de-allocation} -body {
test imageBmap-3.3 {ImgBmapConfigureModel procedure, memory de-allocation} -body {
    image create bitmap i1 -data $data1 -maskdata $data2
    i1 configure -maskdata $data2
} -cleanup {
	image delete i1
} -result {}
test imageBmap-3.4 {ImgBmapConfigureMaster procedure} -body {
test imageBmap-3.4 {ImgBmapConfigureModel procedure} -body {
    image create bitmap i1
    i1 configure -maskdata $data2
} -returnCodes error -result {can't have mask without bitmap}
test imageBmap-3.5 {ImgBmapConfigureMaster procedure} -body {
test imageBmap-3.5 {ImgBmapConfigureModel procedure} -body {
    image create bitmap i1 -data $data1 -maskdata {
	#define foo_width 8
	#define foo_height 16
	static char foo_bits[] = {
	   0xff, 0xff, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
	   0x81, 0x81, 0xff, 0xff, 0xff, 0xff, 0x81, 0x81};
	}
} -returnCodes error -result {bitmap and mask have different sizes}
test imageBmap-3.6 {ImgBmapConfigureMaster procedure} -body {
test imageBmap-3.6 {ImgBmapConfigureModel procedure} -body {
    image create bitmap i1 -data $data1 -maskdata {
	#define foo_width 16
	#define foo_height 8
	static char foo_bits[] = {
	   0xff, 0xff, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
	   0x81, 0x81, 0xff, 0xff, 0xff, 0xff, 0x81, 0x81};
	}
} -returnCodes error -result {bitmap and mask have different sizes}
test imageBmap-3.7 {ImgBmapConfigureMaster procedure} -setup {
test imageBmap-3.7 {ImgBmapConfigureModel procedure} -setup {
    destroy .c
    pack [canvas .c]
} -body {
    image create bitmap i1 -data $data1
    .c create image 100 100 -image i1 -tags i1.1 -anchor nw
    .c create image 200 100 -image i1 -tags i1.2 -anchor nw
    update
499
500
501
502
503
504
505
506
507


508
509
510
511
512
513
514
515
516
517
518
519
520
499
500
501
502
503
504
505


506
507
508
509
510
511
512
513
514
515
516
517
518
519
520







-
-
+
+













    lappend x [info command new*]
} -result {{} newi2 foo.bm {}}


test imageBmap-12.1 {ImgBmapCmdDeletedProc procedure} -body {
    image create bitmap i2 -file foo.bm -maskfile foo2.bm
    rename i2 {}
    list [lsearch -exact [imageNames] i2] [catch {i2 foo} msg] $msg
} -result {-1 1 {invalid command name "i2"}}
    list [expr {"i2" in [imageNames]}] [catch {i2 foo} msg] $msg
} -result {0 1 {invalid command name "i2"}}

removeFile foo.bm
removeFile foo2.bm
imageFinish

# cleanup
cleanupTests
return

# Local Variables:
# mode: tcl
# fill-column: 78
# End:

Changes to tests/imgListFormat.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 default image data format
# ("list format") implementend in the file tkImgListFormat.c.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 2017 Simon Bachmann
# Copyright © 2017 Simon Bachmann
# All rights reserved.
#
# Author: Simon Bachmann ([email protected])

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv

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 (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright (c) 1998 Willem van Schaik (images only)
# Copyright (c) 2008 Donal K. Fellows
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# Copyright © 1998 Willem van Schaik (images only)
# Copyright © 2008 Donal K. Fellows
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit

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 (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 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
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 "photo" image type and the other
# procedures in the file tkImgPhoto.c. It is organized in the standard fashion
# for Tcl tests.
#
# Copyright (c) 1994 The Australian National University
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright (c) 2002-2008 Donal K. Fellows
# Copyright © 1994 The Australian National University
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# Copyright © 2002-2008 Donal K. Fellows
# All rights reserved.
#
# Author: Paul Mackerras ([email protected])

#
# This file is somewhat caothic: the order of the tests does not
# really follow the order of the corresponding functions in
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







-
+







#--------------------------------------------------------------------------
# PhotoFormatThreadExitProc             no tests
# Tk_Create*PhotoImageFormat            no tests
# ImgPhotoCreate                        imgPhoto-2.*
# ImgPhotoCmd                           imgPhoto-4.*, imgPhoto-17.*
# GetExtension:                         no tests
# ParseSubcommandOptions:               imgPhoto-1.*
# ImgPhotoConfigureMaster:              imgPhoto-3.*, imgPhoto-15.*
# 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.*
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







-
-
+
+







# 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
# Tk_PhotoGetMetadata:                  imgPhoto-19.*
# Tk_PhotoSetMetadata:                  imgPhoto-20.*
# Tk_PhotoGetMetadata:                  imgPhoto-21.*
# Tk_PhotoSetMetadata:                  imgPhoto-22.*
#--------------------------------------------------------------------------
#

#
# Some tests are not specific to a function in tkImgPhoto.c. They are:
#

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







+
-
+
+








# 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}
219
220
221
222
223
224
225
226

227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261

262
263
264
265
266
267
268
269
270
271

272
273


274
275
276
277
278
279
280
281
282
283

284
285
286
287
288
289
290
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235

236
237
238
239
240
241
242
243
244

245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262

263
264
265
266
267
268
269
270
271
272
273
274


275
276
277
278
279
280
281
282
283
284
285

286
287
288
289
290
291
292
293







-
+







-
+








-
+

















-
+










+
-
-
+
+









-
+







#     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 {ImgPhotoConfigureMaster procedure} -constraints {
test imgPhoto-3.1 {ImgPhotoConfigureModel procedure} -constraints {
    hasTeapotPhoto
} -body {
    image create photo photo1 -file $teapotPhotoFile
    photo1 configure -file $teapotPhotoFile
} -cleanup {
    image delete photo1
} -result {}
test imgPhoto-3.2 {ImgPhotoConfigureMaster procedure} -constraints {
test imgPhoto-3.2 {ImgPhotoConfigureModel procedure} -constraints {
    hasTeapotPhoto
} -body {
    image create photo photo1 -file $teapotPhotoFile
    list [catch {photo1 configure -file bogus} err] [string tolower $err] \
	[image width photo1] [image height photo1]
} -cleanup {
    image delete photo1
} -result {1 {couldn't open "bogus": no such file or directory} 256 256}
test imgPhoto-3.3 {ImgPhotoConfigureMaster procedure} -constraints {
test imgPhoto-3.3 {ImgPhotoConfigureModel procedure} -constraints {
    hasTeapotPhoto
} -setup {
    destroy .c
    pack [canvas .c]
    update
} -body {
    image create photo photo1
    .c create image 10 10 -image photo1 -tags photo1.1 -anchor nw
    .c create image 300 10 -image photo1 -tags photo1.2 -anchor nw
    update
    photo1 configure -file $teapotPhotoFile
    update
    list [image width photo1] [image height photo1] [.c bbox photo1.1] [.c bbox photo1.2]
} -cleanup {
    destroy .c
    image delete photo1
} -result {256 256 {10 10 266 266} {300 10 556 266}}
test imgPhoto-3.4 {ImgPhotoConfigureMaster: -data <ppm>} -constraints {
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 {ImgPhotoConfigureMaster: -data <png>} -constraints {
    hasTeapotPhoto
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 {ImgPhotoConfigureMaster: -data <default>} -constraints {
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]
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
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







-
+











-
+







    file copy -force $teapotPhotoFile -teapotPhotoFile
    image create photo photo1
    photo1 read -teapotPhotoFile
} -cleanup {
    image delete photo1
    file delete ./-teapotPhotoFile
} -result {}
test imgPhoto-4.76 {ImgPhotoCmd procedure: copy to same image} -constraints {
test imgPhoto-4.75.1 {ImgPhotoCmd procedure: copy to same image} -constraints {
    hasTeapotPhoto
} -setup {
    imageCleanup
    image create photo photo1 -file $teapotPhotoFile
} -body {
    # non-regression test for bug [5239fd749b] - shall just not crash
    photo1 copy photo1 -to 0 0 2000 1000
    photo1 copy photo1 -subsample 2 2 -shrink
} -cleanup {
    imageCleanup
} -result {}
test imgPhoto-4.76 {ImgPhotoCmd, transparancy get: too many options} -setup {
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 \
1333
1334
1335
1336
1337
1338
1339

1340
1341
1342

1343
1344
1345
1346
1347
1348
1349
1350
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345

1346

1347
1348
1349
1350
1351
1352
1353







+


-
+
-







    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
        hasTeapotPhoto hasTranspTeapotPhoto needsTcl867
        hasTranspTeapotPhoto
} -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 {
1496
1497
1498
1499
1500
1501
1502
1503
1504


1505
1506
1507
1508
1509
1510
1511
1499
1500
1501
1502
1503
1504
1505


1506
1507
1508
1509
1510
1511
1512
1513
1514







-
-
+
+







} -result {image "photo2" doesn't exist or is not a photo image}

test imgPhoto-9.1 {ImgPhotoCmdDeletedProc procedure} -constraints {
    hasTeapotPhoto
} -body {
    image create photo photo2 -file $teapotPhotoFile
    rename photo2 {}
    list [lsearch -exact [imageNames] photo2] [catch {photo2 foo} msg] $msg
} -result {-1 1 {invalid command name "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
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
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







-
+

-
+









-
+









-
+






-
+








-
+








-
+






-
+















-
+















-
+












-
+


-
+









-
+









-
+







} -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 18.1-18.9 will cause a segfault on 8.5.19 and lower,
# WARNING - tests 20.1-20.9 will cause a segfault on 8.5.19 and lower,
#           and on 8.6.6 and lower.
test imgPhoto-18.1 {Reject corrupted GIF (binary string)} -setup {
test imgPhoto-20.1 {Reject corrupted GIF (binary string)} -setup {
    set data [binary decode base64 {
	R0lGODlhAAQABP8zM/8z/zP/MzP/////M////yH5CiwheLrcLTBCd6Tv2qW16tdK4jhV
	5qpraXIvM1JlNyAgOw==
    }]
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp
test imgPhoto-18.2 {Reject corrupted GIF (base 64 string)} -setup {
test imgPhoto-20.2 {Reject corrupted GIF (base 64 string)} -setup {
    set data {
	R0lGODlhAAQABP8zM/8z/zP/MzP/////M////yH5CiwheLrcLTBCd6Tv2qW16tdK4jhV
	5qpraXIvM1JlNyAgOw==
    }
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp
test imgPhoto-18.3 {Reject corrupted GIF (file)} -setup {
test imgPhoto-20.3 {Reject corrupted GIF (file)} -setup {
    set fileName [file join [file dirname [info script]] corruptMangled.gif]
} -body {
    image create photo gif1 -file $fileName
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp
test imgPhoto-18.4 {Reject truncated GIF (binary string)} -setup {
test imgPhoto-20.4 {Reject truncated GIF (binary string)} -setup {
    set data [binary decode base64 {
	R0lGODlhEAAQAMIHAAAAADMz//8zM/8z/zP/MzP///8=
    }]
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map}
test imgPhoto-18.5 {Reject truncated GIF (base 64 string)} -setup {
test imgPhoto-20.5 {Reject truncated GIF (base 64 string)} -setup {
    set data {
	R0lGODlhEAAQAMIHAAAAADMz//8zM/8z/zP/MzP///8=
    }
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map}
test imgPhoto-18.6 {Reject truncated GIF (file)} -setup {
test imgPhoto-20.6 {Reject truncated GIF (file)} -setup {
    set fileName [file join [file dirname [info script]] corruptTruncated.gif]
} -body {
    image create photo gif1 -file $fileName
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map}
test imgPhoto-18.7 {Reject corrupted GIF (> 4Gb) (binary string)} -constraints {
test imgPhoto-20.7 {Reject corrupted GIF (> 4Gb) (binary string)} -constraints {
    nonPortable
} -setup {
    # About the non portability constraint of this test: see ticket [cc42cc18a5]
    # If there is insufficient memory, the error message
    # {not enough free memory for image buffer} should be returned.
    # Instead, some systems (e.g. FreeBSD 11.1) terminate the test interpreter.
    set data [binary decode base64 {
	R0lGODlhwmYz//8zM/8z/zP/MzP/////M////yH5Ciwhe
	LrcLTBCd6Tv2qW16tdK4jhV5qpraXIvM1JlNyAgOw==
    }]
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp
test imgPhoto-18.8 {Reject corrupted GIF (> 4Gb) (base 64 string)} -constraints {
test imgPhoto-20.8 {Reject corrupted GIF (> 4Gb) (base 64 string)} -constraints {
    nonPortable
} -setup {
    # About the non portability constraint of this test: see ticket [cc42cc18a5]
    # If there is insufficient memory, the error message
    # {not enough free memory for image buffer} should be returned.
    # Instead, some systems (e.g. FreeBSD 11.1) terminate the test interpreter.
    set data {
	R0lGODlhwmYz//8zM/8z/zP/MzP/////M////yH5Ciwhe
	LrcLTBCd6Tv2qW16tdK4jhV5qpraXIvM1JlNyAgOw==
    }
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp
test imgPhoto-18.9 {Reject corrupted GIF (> 4Gb) (file)} -constraints {
test imgPhoto-20.9 {Reject corrupted GIF (> 4Gb) (file)} -constraints {
    nonPortable
} -setup {
    # About the non portability constraint of this test: see ticket [cc42cc18a5]
    # If there is insufficient memory, the error message
    # {not enough free memory for image buffer} should be returned.
    # Instead, some systems (e.g. FreeBSD 11.1) terminate the test interpreter.
    set fileName [file join [file dirname [info script]] corruptMangled4G.gif]
} -body {
    image create photo gif1 -file $fileName
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {error reading color map|not enough free memory for image buffer} -match regexp
test imgPhoto-18.10 {Valid GIF (binary string)} -setup {
test imgPhoto-20.10 {Valid GIF (binary string)} -setup {
    # Test the binary string reader with a valid GIF.
    # This is not tested elsewhere.
    # Tests 18.11, 18.12, with matching data, are included for completeness.
    # Tests 20.11, 20.12, with matching data, are included for completeness.
    set data [binary decode base64 {
	R0lGODlhEAAQAMIHAAAAADMz//8zM/8z/zP/MzP/////M////yH5BAEKAAcALAAA
	AAAQABAAAAMheLrcLTBCd6QV79qlterXB0riOFXmmapraXIvM1IdZTcJADs=
    }]
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -result gif1
test imgPhoto-18.11 {Valid GIF (base 64 string)} -setup {
test imgPhoto-20.11 {Valid GIF (base 64 string)} -setup {
    set data {
	R0lGODlhEAAQAMIHAAAAADMz//8zM/8z/zP/MzP/////M////yH5BAEKAAcALAAA
	AAAQABAAAAMheLrcLTBCd6QV79qlterXB0riOFXmmapraXIvM1IdZTcJADs=
    }
} -body {
    image create photo gif1 -data $data
} -cleanup {
    catch {image delete gif1}
} -result gif1
test imgPhoto-18.12 {Valid GIF (file)} -setup {
test imgPhoto-20.12 {Valid GIF (file)} -setup {
    set fileName [file join [file dirname [info script]] red.gif]
} -body {
    image create photo gif1 -file $fileName
} -cleanup {
    catch {image delete gif1}
} -result gif1

Changes to 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
1
2
3
4

5
6
7
8
9
10
11
12
13
14
15
16
17
18











19
20
21
22
23
24
25
26
27
28
29


30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45




-
+









+

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






+







# 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 (c) 2018 Rene Zaumseil
# 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) {\
    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 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>}
            </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 {
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
83
84

85
86
87
88
89
90
91

92

93
94
95
96
97
98
99

100
101
102
103
104
105
106
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87


88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103

104
105
106
107
108
109
110
111







+








-
-
+







+
-
+






-
+







    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 {
test imgSVGnano-1.6 {simple image from file 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 {
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 {
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}

148
149
150
151
152
153
154
155

156
157
158
159
160
161
162
163

164
165
166
167
168
169
170
153
154
155
156
157
158
159

160
161
162
163
164
165
166
167

168
169
170
171
172
173
174
175







-
+







-
+







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

190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209






































210
211
212
213
214
215
216
217
218
219
220
195
196
197
198
199
200
201

202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262







-












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











    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}

test imgSVGnano-5.2 {bug d6e9b4db40 - "<svg" and ">" must be present} -body {
    image create photo foo -format svg -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">\
			<sERRORvBADFILEg xmlns="http://www.w3.org/2000/svg">\
			<circle cx="6.5cm" cy="2cm" r="100" transform="skewX(1 1)"/>\
			</g></svg>}
} -returnCodes error -result {couldn't recognize image data}

};# 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 (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 © 1993-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

583
584
585
586
587
588
589
590

591
592
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
598
599

600
601
602
603
604
605
606
607







-
+









-
+







    destroy .l2
} -result {el1 el5 5}
test listbox-3.36 {ListboxWidgetCmd procedure, "delete" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    .l2 delete -3 2
    .l2 delete -1 2
    .l2 get 0 end
} -cleanup {
    destroy .l2
} -result {el3 el4 el5 el6 el7}
test listbox-3.37 {ListboxWidgetCmd procedure, "delete" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    .l2 delete -3 -1
    .l2 delete -1 -1
    .l2 get 0 end
} -cleanup {
    destroy .l2
} -result {el0 el1 el2 el3 el4 el5 el6 el7}
test listbox-3.38 {ListboxWidgetCmd procedure, "delete" option} -setup {
    destroy .l2
} -body {
680
681
682
683
684
685
686
687

688
689
690

691
692
693
694
695
696
697
680
681
682
683
684
685
686

687
688
689

690
691
692
693
694
695
696
697







-
+


-
+







} -cleanup {
    destroy .l2
} -result {{two words} el4 el5 el6 el7}
test listbox-3.49 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get -1
} -result {}
test listbox-3.50 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get -2 -1
    .l get -1 -1
} -result {}
test listbox-3.51 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get -2 3
    .l get -1 3
} -result {el0 el1 el2 el3}
test listbox-3.52 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get 12 end
} -result {el12 el13 el14 el15 el16 el17}
test listbox-3.53 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get 12 20
} -result {el12 el13 el14 el15 el16 el17}
714
715
716
717
718
719
720
721

722
723
724
725
726
727
728
714
715
716
717
718
719
720

721
722
723
724
725
726
727
728







-
+







    .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
test listbox-3.64 {ListboxWidgetCmd procedure, "insert" option} -body {
2125
2126
2127
2128
2129
2130
2131
2132

2133
2134
2135

2136
2137
2138
2139
2140
2141
2142
2125
2126
2127
2128
2129
2130
2131

2132
2133
2134

2135
2136
2137
2138
2139
2140
2141
2142







-
+


-
+







} -result {}
test listbox-10.19 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index -2
    .l index -1
} -cleanup {
    destroy .l
} -result  -1
} -result -1
test listbox-10.20 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    .l delete 0 end
    update
2374
2375
2376
2377
2378
2379
2380
2381

2382
2383
2384
2385
2386
2387
2388
2374
2375
2376
2377
2378
2379
2380

2381
2382
2383
2384
2385
2386
2387
2388







-
+







    .l select set 0 end
    .l curselection
} -result {}
test listbox-15.4 {ListboxSelect procedure, boundary conditions for indices} -body {
    .l delete 0 end
    .l insert 0 a b c d e f
    .l select clear 0 end
    .l select set -2 -1
    .l select set -1 -1
    .l curselection
} -result {}
test listbox-15.5 {ListboxSelect procedure, boundary conditions for indices} -body {
    .l delete 0 end
    .l insert 0 a b c d e f
    .l select clear 0 end
    .l select set -1 3
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
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







-
+

-

-
-
+
+

-
+

-
+



-
-
+





-

-
-
+
+

-
+

-
+

-
+



-
-
+







    .l curselection
} -cleanup {
    destroy .l
} -result 2
test listbox-21.9 {ListboxListVarProc, test hscrollbar after listvar mod} -setup {
    destroy .l
} -body {
    catch {unset x}
    set x {}
    listbox .l -font $fixed -width 10 -xscrollcommand "record x" -listvar x
    set log {}
    pack .l
    set timeout [after 500 {set log timeout}]
    vwait log
    update idletasks
    set log {}
    lappend x "0000000000"
    update
    update idletasks
    lappend x "00000000000000000000"
    update
    update idletasks
    set log
} -cleanup {
    destroy .l
    after cancel $timeout
} -result [list {x 0 1} {x 0 1} {x 0 0.5}]
} -result [list {x 0 1} {x 0 0.5}]
test listbox-21.10 {ListboxListVarProc, test hscrollbar after listvar mod} -setup {
    destroy .l
} -body {
    catch {unset x}
    listbox .l -font $fixed -width 10 -xscrollcommand "record x" -listvar x
    set log {}
    pack .l
    set timeout [after 500 {set log timeout}]
    vwait log
    update idletasks
    set log {}
    lappend x "0000000000"
    update
    update idletasks
    lappend x "00000000000000000000"
    update
    update idletasks
    set x [list "0000000000"]
    update
    update idletasks
    set log
} -cleanup {
    destroy .l
    after cancel timeout
} -result [list {x 0 1} {x 0 1} {x 0 0.5} {x 0 1}]
} -result [list {x 0 1} {x 0 0.5} {x 0 1}]
test listbox-21.11 {ListboxListVarProc, bad list} -setup {
    destroy .l
} -body {
    catch {unset x}
    listbox .l -listvar x
    set x [list a b c d]
    catch {set x "this is a \" bad list"} result
2760
2761
2762
2763
2764
2765
2766
2767

2768
2769
2770
2771
2772
2773
2774
2756
2757
2758
2759
2760
2761
2762

2763
2764
2765
2766
2767
2768
2769
2770







-
+







    destroy .l
} -body {
    catch {unset x}
    listbox .l -font $fixed -height 3 -yscrollcommand "record y" -listvar x
    update
    set log {}
    pack .l
    set timeout [after 500 {set log timeout}]
    set timeout [after 500 {lappend log timeout3}]
    vwait log
    update
    lappend x a b c d e f
    vwait log
    set log
} -cleanup {
    destroy .l
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
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







-

+
+
-
+
-

-
+






-
+









# UpdateHScrollbar
test listbox-22.1 {UpdateHScrollbar} -setup {
    destroy .l
} -body {
    listbox .l -font $fixed -width 10 -xscrollcommand "record x"
    set log {}
    pack .l
    update idletasks
    set log {}
    set timeout [after 500 {set log timeout}]
    set timeout [after 500 {lappend log timeout4}]
    vwait log
    .l insert end "0000000000"
    update
    vwait log
    .l insert end "00000000000000000000"
    vwait log
    set log
} -cleanup {
    destroy .l
    after cancel $timeout
} -result [list {x 0 1} {x 0 1} {x 0 0.5}]
} -result [list {x 0 1} {x 0 0.5}]


# ConfigureListboxItem
test listbox-23.1 {ConfigureListboxItem} -setup {
    destroy .l
} -body {
    listbox .l
2854
2855
2856
2857
2858
2859
2860
2861

2862
2863
2864
2865
2866
2867
2868
2850
2851
2852
2853
2854
2855
2856

2857
2858
2859
2860
2861
2862
2863
2864







-
+







} -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? ?-option value ...?"}
} -result {wrong # args: should be ".l itemconfigure index ?-option value ...?"}
test listbox-23.5 {ConfigureListboxItem, multiple calls} -setup {
    destroy .l
} -body {
    listbox .l
    set i 0
    foreach color {red orange yellow green blue white violet} {
	.l insert end $color
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3213
3214
3215
3216
3217
3218
3219












-
-
-
-
-
resetGridInfo
deleteWindows
option clear

# cleanup
cleanupTests
return





Changes to tests/main.test.

1
2
3
4
5
6
7
8


9
10
11
12
13
14
15
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 (c) 1997 by Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 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
54
55
23
24
25
26
27
28
29

30

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

46

47
48
49
50
51
52
53







-
+
-















-
+
-








test main-2.1 {Tk_MainEx: -encoding option} -constraints stdio -setup {
	set script [makeFile {} script]
	file delete $script
	set f [open $script w]
	fconfigure $f -encoding utf-8
	puts $f {puts [list $argv0 $argv $tcl_interactive]}
	puts -nonewline $f {puts [string equal \u20ac }
	puts $f {puts [string equal \u20AC €]; exit}
	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 -nonewline $f {puts [string equal \u20ac }
	puts $f {puts [string equal \u20AC €]; exit}
	puts $f "\u20ac]; exit"
	close $f
	catch {set f [open "|[list [interpreter] -encoding ascii script]" r]}
} -body {
	read $f
} -cleanup {
	close $f
	removeFile script
72
73
74
75
76
77
78
79

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

98
99
100
101
102
103
104
70
71
72
73
74
75
76

77

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101







-
+
-
















-
+








test main-2.3 {Tk_MainEx: -encoding option} -constraints stdio -setup {
	set script [makeFile {} script]
	file delete $script
	set f [open $script w]
	fconfigure $f -encoding utf-8
	puts $f {puts [list $argv0 $argv $tcl_interactive]}
	puts -nonewline $f {puts [string equal \u20ac }
	puts $f {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
1
2
3


4
5
6
7
8
9
10
11
12



-
-
+
+







# This file is a Tcl script to test menus in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1995-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1995-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit
1854
1855
1856
1857
1858
1859
1860








1861
1862
1863
1864
1865
1866
1867
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875







+
+
+
+
+
+
+
+







    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
2056
2057
2058
2059
2060
2061
2062
2063

2064
2065
2066
2067
2068
2069
2070
2064
2065
2066
2067
2068
2069
2070

2071
2072
2073
2074
2075
2076
2077
2078







-
+







    destroy .m1
} -body {
    menu .m1
    set tearoff1 [tk::TearOffMenu .m1]
    set tearoff2 [tk::TearOffMenu .m1]
    list [destroy $tearoff1] [destroy .m1]
} -returnCodes ok -result {{} {}}
test menu-5.9 {DestroyMenuInstace - master menu} -setup {
test menu-5.9 {DestroyMenuInstace - main menu} -setup {
    destroy .m1
} -body {
    menu .m1
    tk::TearOffMenu .m1
    destroy .m1
} -returnCodes ok
test menu-5.10 {DestroyMenuInstance - freeing entries} -setup {

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 (c) 1996-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1996-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test
imageInit
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







-
+







} -body {
    menu .m1
    .m1 add command -label "foo" -state active
    set tearoff [tk::TearOffMenu .m1 40 40]
    $tearoff index active
} -cleanup {
    deleteWindows
} -result {none}
} -result none
test menuDraw-15.3 {TkPostTearoffMenu - post command} -setup {
    deleteWindows
} -body {
    catch {unset foo}
    menu .m1 -postcommand "set foo .m1"
    .m1 add command -label "foo"
    list [catch {tk::TearOffMenu .m1 40 40}] [set foo] [unset foo] [destroy .m1]

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 (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 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

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 (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 by Ajuba Solutions.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-2000 Ajuba Solutions.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::loadTestedCommands
eval tcltest::configure $argv

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 (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 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/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 (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 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 (c) 1991-1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1991-1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 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
25
26
27
28
29
30
31
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46








+
+
+
+
+

-
+







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
448
449
450
451
452
453
454
455

456
457
458

459
460
461
462
463
464
465
453
454
455
456
457
458
459

460
461
462

463
464
465
466
467
468
469
470







-
+


-
+







    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, forget, info, propagate, or slaves}
} -returnCodes error -result {bad option "gorp": must be configure, content, forget, info, or propagate}
test oldpack-8.4 {syntax errors} -body {
    pack a .pack
} -returnCodes error -result {bad option "a": must be configure, forget, info, propagate, or slaves}
} -returnCodes error -result {bad option "a": must be configure, content, forget, info, or propagate}
test oldpack-8.5 {syntax errors} -body {
    pack after foobar
} -returnCodes error -result {bad window path name "foobar"}
test oldpack-8.6 {syntax errors} -setup {
    destroy .pack.yellow
} -body {
    frame .pack.yellow -bg yellow
488
489
490
491
492
493
494
495

496
497
498
499
500
501
502
493
494
495
496
497
498
499

500
501
502
503
504
505
506
507







-
+







    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 {
523
524
525
526
527
528
529
530

531
532
533
534
535
536
537

538
539
540
541
542
543

544
545
546

547
548
549
550
551
552
528
529
530
531
532
533
534

535
536
537
538
539
540
541

542
543
544
545
546
547

548
549
550
551
552
553
554
555
556
557
558







-
+






-
+





-
+



+







# Test "pack info" command output.

test oldpack-9.1 {information output} -body {
    pack append .pack .pack.blue {top fillx frame n} \
    .pack.red {bottom filly frame s} .pack.green {left fill frame w} \
    .pack.violet {right expand frame e}
    list [pack slaves .pack] [pack info .pack.blue] [pack info .pack.red] \
    list [pack content .pack] [pack info .pack.blue] [pack info .pack.red] \
        [pack info .pack.green] [pack info .pack.violet]
} -result {{.pack.blue .pack.red .pack.green .pack.violet} {-in .pack -anchor n -expand 0 -fill x -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top} {-in .pack -anchor s -expand 0 -fill y -ipadx 0 -ipady 0 -padx 0 -pady 0 -side bottom} {-in .pack -anchor w -expand 0 -fill both -ipadx 0 -ipady 0 -padx 0 -pady 0 -side left} {-in .pack -anchor e -expand 1 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side right}}
test oldpack-9.2 {information output} -body {
    pack append .pack .pack.blue {padx 10 frame nw} \
    .pack.red {pady 20 frame ne} .pack.green {frame se} \
    .pack.violet {frame sw}
    list [pack slaves .pack] [pack info .pack.blue] [pack info .pack.red] \
    list [pack content .pack] [pack info .pack.blue] [pack info .pack.red] \
        [pack info .pack.green] [pack info .pack.violet]
} -result {{.pack.blue .pack.red .pack.green .pack.violet} {-in .pack -anchor nw -expand 0 -fill none -ipadx 0 -ipady 0 -padx 5 -pady 0 -side top} {-in .pack -anchor ne -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 10 -side top} {-in .pack -anchor se -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top} {-in .pack -anchor sw -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top}}
test oldpack-9.3 {information output} -body {
    pack append .pack .pack.blue {frame center} .pack.red {frame center} \
    .pack.green {frame c} .pack.violet {frame c}
    list [pack slaves .pack] [pack info .pack.blue] [pack info .pack.red] \
    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 (c) 1991-1993 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1991-1993 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

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







-
+







} -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\xf3wn
test option-15.11 {database files} {option get . {x 4} color} brówn

test option-16.1 {ReadOptionFile} -body {
    set option4 [makeFile {} option.file3]
    set file [open $option4 w]
    fconfigure $file -translation crlf
    puts $file "*x7: true\n*x8: false"
    close $file

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
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 out the "pack" command of Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1993 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1993 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 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(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
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
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







-
+






-
+






-
+






-
+







-
+






-
+






-
+






-
+






-
+






-
+



















-
+






-
+




-
+








-
+











-
+







pack forget .pack.right .pack.bottom

test pack-9.1 {window ordering} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack .pack.a -after .pack.b
    pack slaves .pack
    pack content .pack
} -result {.pack.b .pack.a .pack.c .pack.d}
test pack-9.2 {window ordering} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack .pack.a -after .pack.a
    pack slaves .pack
    pack content .pack
} -result {.pack.a .pack.b .pack.c .pack.d}
test pack-9.3 {window ordering} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack .pack.a -before .pack.d
    pack slaves .pack
    pack content .pack
} -result {.pack.b .pack.c .pack.a .pack.d}
test pack-9.4 {window ordering} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack .pack.d -before .pack.a
    pack slaves .pack
    pack content .pack
} -result {.pack.d .pack.a .pack.b .pack.c}
test pack-9.5 {window ordering} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack propagate .pack.c 0
    pack .pack.a -in .pack.c
    list [pack slaves .pack] [pack slaves .pack.c]
    list [pack content .pack] [pack content .pack.c]
} -result {{.pack.b .pack.c .pack.d} .pack.a}
test pack-9.6 {window ordering} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack .pack.a -in .pack
    pack slaves .pack
    pack content .pack
} -result {.pack.b .pack.c .pack.d .pack.a}
test pack-9.7 {window ordering} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d -side top
    pack .pack.a -padx 0
    pack slaves .pack
    pack content .pack
} -result {.pack.a .pack.b .pack.c .pack.d}
test pack-9.8 {window ordering} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c
    pack .pack.d
    pack slaves .pack
    pack content .pack
} -result {.pack.a .pack.b .pack.c .pack.d}
test pack-9.9 {window ordering} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d
    pack .pack.b .pack.d .pack.c -before .pack.a
    pack slaves .pack
    pack content .pack
} -result {.pack.b .pack.d .pack.c .pack.a}
test pack-9.10 {window ordering} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a .pack.b .pack.c .pack.d
    pack .pack.a .pack.c .pack.d .pack.b -after .pack.a
    pack slaves .pack
    pack content .pack
} -result {.pack.a .pack.c .pack.d .pack.b}

test pack-10.1 {retaining/clearing configuration state} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side bottom -anchor n -padx 1 -pady 2 -ipadx 3 -ipady 4 \
    -fill both -expand 1
    pack forget .pack.a
    pack .pack.a
    pack info .pack.a
} -result {-in .pack -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top}
test pack-10.2 {retaining/clearing configuration state} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side bottom -anchor n -padx 1 -pady 2 -ipadx 3 -ipady 4 \
    -fill both -expand 1
    pack .pack.a -pady 14
    pack info .pack.a
} -result {-in .pack -anchor n -expand 1 -fill both -ipadx 3 -ipady 4 -padx 1 -pady 14 -side bottom}
test pack-10.3 {bad -in window does not change master} -setup {
test pack-10.3 {bad -in window does not change container window} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    set result [list [winfo manager .pack.a]]
    catch {pack .pack.a -in .pack.a}
    lappend result [winfo manager .pack.a]
} -result {{} {}}
test pack-10.4 {bad -in window does not change master} -setup {
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]
1130
1131
1132
1133
1134
1135
1136
1137

1138
1139
1140
1141
1142
1143
1144
1132
1133
1134
1135
1136
1137
1138

1139
1140
1141
1142
1143
1144
1145
1146







-
+







test pack-12.3 {command options and errors} -body {
    pack configure x
} -returnCodes error -result {bad argument "x": must be name of window}
test pack-12.4 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack configure .pack.b .pack.c
    pack slaves .pack
    pack content .pack
} -result {.pack.b .pack.c}
test pack-12.5 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .foo
} -returnCodes error -result {bad window path name ".foo"}
test pack-12.6 {command options and errors} -setup {
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
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







-
+





-
+




-
+





-
+







} -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 slaves .pack
    pack content .pack
} -result {.pack.b .pack.c}
test pack-12.37 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    .pack configure -width 300 -height 200
    pack propagate .pack 0
    pack .pack.a
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
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







-
+




-
-
+
+



-
+




-
+





-
+










-
+







    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack propagate .pack foo bar
} -returnCodes error -result {wrong # args: should be "pack propagate window ?boolean?"}
test pack-12.42 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack slaves
    pack content
} -returnCodes error -result {wrong # args: should be "pack option arg ?arg ...?"}
test pack-12.43 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack slaves a b
} -returnCodes error -result {wrong # args: should be "pack slaves window"}
    pack content a b
} -returnCodes error -result {wrong # args: should be "pack content window"}
test pack-12.44 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack slaves .x
    pack content .x
} -returnCodes error -result {bad window path name ".x"}
test pack-12.45 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack slaves .pack.a
    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, forget, info, propagate, or slaves}
} -returnCodes error -result {bad option "lousy": must be configure, content, forget, info, or propagate}

test pack-13.1 {window deletion} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d .pack.right .pack.bottom
} -body {
    pack .pack.right -side right
    pack .pack.bottom -side bottom
    pack .pack.a .pack.d .pack.b .pack.c -side top
    update
    destroy .pack.d
    update
    set result [list [pack slaves .pack] [winfo geometry .pack.a] \
    set result [list [pack content .pack] [winfo geometry .pack.a] \
        [winfo geometry .pack.b] [winfo geometry .pack.c]]
} -result {{.pack.right .pack.bottom .pack.a .pack.b .pack.c} 20x40+30+0 50x30+15+40 80x80+0+70}

test pack-14.1 {respond to changes in expansion} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d .pack.right .pack.bottom
} -body {
    pack .pack.right -side right
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
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







-
+








-
+











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
















-
+


-


-
+



-
+


-
+
+











-
+


-


-
+



-
+




-
+

















-
+







    lappend result [winfo manager .pack.a]
    pack .pack.a
    lappend result [winfo manager .pack.a]
    pack forget .pack.a
    lappend result [winfo manager .pack.a]
} -result {{} pack {}}

test pack-17.1 {PackLostSlaveProc procedure} -setup {
test pack-17.1 {PackLostContentProc procedure} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a
    update
    place .pack.a -x 40 -y 10
    update
    list [winfo manager .pack.a] [winfo geometry .pack.a]
} -result {place 20x40+40+10}
test pack-17.2 {PackLostSlaveProc procedure} -setup {
test pack-17.2 {PackLostContentProc procedure} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a
    update
    place .pack.a -x 40 -y 10
    update
    winfo manager .pack.a
    winfo geometry .pack.a
    pack info .pack.a
} -returnCodes error -result {window ".pack.a" isn't packed}

if {[tk windowingsystem] ne "aqua"} {
    proc packUpdate {} {
	update
    }
} else {
    proc packUpdate {} {
    }
}

test pack-18.1 {unmap slaves when master unmapped} -constraints {
    tempNotPc
test pack-18.1 {unmap content when container unmapped} -constraints {
    tempNotPc failsOnUbuntu failsOnXQuarz
} -setup {
    eval destroy [winfo child .pack]
} -body {
    # adjust the position of .pack before test to avoid a screen switch
    # that occurs with window managers that have desktops four times as big
    # as the screen (screen switch causes scale and other tests to fail).

    wm geometry .pack +100+100

    # On the PC, when the width/height is configured while the window is
    # unmapped, the changes don't take effect until the window is remapped.
    # Who knows why?

    eval destroy [winfo child .pack]
    frame .pack.a -width 100 -height 50 -relief raised -bd 2
    pack .pack.a
    update
    update idletasks
    set result [winfo ismapped .pack.a]
    wm iconify .pack
    update
    lappend result [winfo ismapped .pack.a]
    .pack.a configure -width 200 -height 75
    update
    update idletasks
    lappend result [winfo width .pack.a ] [winfo height .pack.a] \
    [winfo ismapped .pack.a]
    wm deiconify .pack
    update
    packUpdate
    lappend result [winfo ismapped .pack.a]
} -result {1 0 200 75 0 1}
test pack-18.2 {unmap slaves when master unmapped} -setup {

test pack-18.2 {unmap content when container unmapped} -constraints {failsOnUbuntu failsOnXQuarz} -setup {
    eval destroy [winfo child .pack]
} -body {
    # adjust the position of .pack before test to avoid a screen switch
    # that occurs with window managers that have desktops four times as big
    # as the screen (screen switch causes scale and other tests to fail).

    wm geometry .pack +100+100
    frame .pack.a -relief raised -bd 2
    frame .pack.b -width 70 -height 30 -relief sunken -bd 2
    pack .pack.a
    pack .pack.b -in .pack.a
    update
    update idletasks
    set result [winfo ismapped .pack.b]
    wm iconify .pack
    update
    lappend result [winfo ismapped .pack.b]
    .pack.b configure -width 100 -height 30
    update
    update idletasks
    lappend result [winfo width .pack.b ] [winfo height .pack.b] \
    [winfo ismapped .pack.b]
    wm deiconify .pack
    update
    packUpdate
    lappend result [winfo ismapped .pack.b]
} -result {1 0 100 30 0 1}

test pack-19.1 {test respect for internalborder} -setup {
    catch {eval pack forget [pack slaves .pack]}
    catch {eval pack forget [pack content .pack]}
    destroy .pack.l .pack.lf
} -body {
    wm geometry .pack 200x200
    frame .pack.l -width 15 -height 10
    labelframe .pack.lf -labelwidget .pack.l
    pack .pack.lf -fill both -expand 1
    frame .pack.lf.f
    pack .pack.lf.f -fill both -expand 1
    update
    set res [list [winfo geometry .pack.lf.f]]
    .pack.lf configure -labelanchor e -padx 3 -pady 5
    update
    lappend res [winfo geometry .pack.lf.f]
} -cleanup {
    destroy .pack.l .pack.lf
} -result {196x188+2+10 177x186+5+7}
test pack-19.2 {test support for minreqsize} -setup {
    catch {eval pack forget [pack slaves .pack]}
    catch {eval pack forget [pack content .pack]}
    destroy .pack.l .pack.lf
} -body {
    wm geometry .pack {}
    frame .pack.l -width 150 -height 100
    labelframe .pack.lf -labelwidget .pack.l
    pack .pack.lf -fill both -expand 1
    frame .pack.lf.f -width 20 -height 25

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
47
48
49
50
51
52
53
54
55

56
57
58
59
60
61
62
63
64
65
66
67
68
69

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

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

98
99
100
101
102
103
104
105
106

107
108
109
110
111
112

113
114
115
116
117
118
119
120
121

122
123
124
125
126
127

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

141
142

143
144
145
146
147
148
149
150
151
152
153
154
155
156

157
158

159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

174
175

176
177
178
179
180
181
182
183
184
185
186
187
188
189

190
191

192
193
194
195
196
197
198
199
200
201
202
203
204
205

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

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

233
234

235
236
237
238
239
240
241
242
243
244
245
246
247

248
249

250
251
252
253
254
255
256
257
258
259
260
261
262
263
264

265
266
267
268
269
270
271
1
2
3
4

5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
20
21
22
23
24

25
26

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

39
40

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

55
56
57
58
59
60
61
62
63
64
65
66
67
68

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

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

97
98
99
100
101
102
103
104
105

106
107
108
109
110
111

112
113
114
115
116
117
118
119
120

121
122
123
124
125
126

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

140
141

142
143
144
145
146
147
148
149
150
151
152
153
154
155

156
157

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

173
174

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

189
190

191
192
193
194
195
196
197
198
199
200
201
202
203
204

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

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

232
233

234
235
236
237
238
239
240
241
242
243
244
245
246

247
248

249
250
251
252
253
254
255
256
257
258
259
260
261
262
263

264
265
266
267
268
269
270
271




-
+







-
+











-
+

-
+











-
+

-
+













-
+













-
+













-
+













-
+








-
+





-
+








-
+





-
+












-
+

-
+













-
+

-
+














-
+

-
+













-
+

-
+













-
+













-
+












-
+

-
+












-
+

-
+














-
+







# 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 (c) 2008 Peter Spjuth
# Copyright © 2008 Peter Spjuth
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::*

test packgrid-1.1 {pack and grid in same master} -setup {
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 . which already has slaves managed by grid}
} -result {cannot use geometry manager pack inside . because grid is already managing it's content windows}

test packgrid-1.2 {pack and grid in same master} -setup {
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 . which already has slaves managed by pack}
} -result {cannot use geometry manager grid inside . because pack is already managing it's content windows}

test packgrid-1.3 {pack and grid in same master} -setup {
test packgrid-1.3 {pack and grid in same container window} -setup {
    grid propagate . false
    pack propagate . true
    label .p -text PACK
    label .g -text GRID
} -body {
    # Ok if one is non-propagating
    grid .g
    pack .p
} -cleanup {
    destroy .p
    destroy .g
} -result {}

test packgrid-1.4 {pack and grid in same master} -setup {
test packgrid-1.4 {pack and grid in same container window} -setup {
    grid propagate . false
    pack propagate . true
    label .p -text PACK
    label .g -text GRID
} -body {
    # Ok if one is non-propagating
    pack .p
    grid .g
} -cleanup {
    destroy .p
    destroy .g
} -result {}

test packgrid-1.5 {pack and grid in same master} -setup {
test packgrid-1.5 {pack and grid in same container window} -setup {
    grid propagate . true
    pack propagate . false
    label .p -text PACK
    label .g -text GRID
} -body {
    # Ok if one is non-propagating
    grid .g
    pack .p
} -cleanup {
    destroy .p
    destroy .g
} -result {}

test packgrid-1.6 {pack and grid in same master} -setup {
test packgrid-1.6 {pack and grid in same container window} -setup {
    grid propagate . true
    pack propagate . false
    label .p -text PACK
    label .g -text GRID
} -body {
    # Ok if one is non-propagating
    pack .p
    grid .g
} -cleanup {
    destroy .p
    destroy .g
} -result {}

test packgrid-1.7 {pack and grid in same master} -setup {
test packgrid-1.7 {pack and grid in same container window} -setup {
    grid propagate . true
    pack propagate . true
    label .p -text PACK
    label .g -text GRID
} -body {
    # Basic conflict should stop widget from being handled
    grid .g
    catch { pack .p }
    pack slaves .
    pack content .
} -cleanup {
    destroy .p
    destroy .g
} -result {}

test packgrid-1.8 {pack and grid in same master} -setup {
test packgrid-1.8 {pack and grid in same container window} -setup {
    grid propagate . true
    pack propagate . true
    label .p -text PACK
    label .g -text GRID
} -body {
    # Basic conflict should stop widget from being handled
    pack .p
    catch { grid .g }
    grid slaves .
    grid content .
} -cleanup {
    destroy .p
    destroy .g
} -result {}

test packgrid-2.1 {pack and grid in same master, change propagation} -setup {
test packgrid-2.1 {pack and grid in same container window, change propagation} -setup {
    grid propagate . false
    pack propagate . true
    label .p -text PACK
    label .g -text GRID
    pack .p
    grid .g
    update
} -body {
    grid propagate . true
} -returnCodes error -cleanup {
    destroy .p
    destroy .g
} -result {cannot use geometry manager grid inside . which already has slaves managed by pack}
} -result {cannot use geometry manager grid inside . because pack is already managing it's content windows}

test packgrid-2.2 {pack and grid in same master, change propagation} -setup {
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 . which already has slaves managed by grid}
} -result {cannot use geometry manager pack inside . because grid is already managing it's content windows}

test packgrid-2.3 {pack and grid in same master, change propagation} -setup {
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 . which already has slaves managed by grid}
} -result {cannot use geometry manager pack inside . because grid is already managing it's content windows}

test packgrid-2.4 {pack and grid in same master, change propagation} -setup {
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 . which already has slaves managed by pack}
} -result {cannot use geometry manager grid inside . because pack is already managing it's content windows}

test packgrid-3.1 {stealing slave} -setup {
test packgrid-3.1 {stealing content} -setup {
    grid propagate . true
    pack propagate . true
    label .p -text PACK
    label .g -text GRID
} -body {
    # Ok to steal if the other one is emptied
    grid .g
    pack .g
} -cleanup {
    destroy .p
    destroy .g
} -result {}

test packgrid-3.2 {stealing slave} -setup {
test packgrid-3.2 {stealing content} -setup {
    grid propagate . true
    pack propagate . true
    label .p -text PACK
    label .g -text GRID
} -body {
    # Ok to steal if the other one is emptied
    pack .g
    grid .g
} -cleanup {
    destroy .p
    destroy .g
} -result {}

test packgrid-3.3 {stealing slave} -setup {
test packgrid-3.3 {stealing content} -setup {
    grid propagate . true
    pack propagate . true
    label .p -text PACK
    label .g -text GRID
} -body {
    # Not ok to steal if the other one is not emptied
    grid .g
    grid .p
    pack .g
}  -returnCodes error -cleanup {
    destroy .p
    destroy .g
} -result {cannot use geometry manager pack inside . which already has slaves managed by grid}
} -result {cannot use geometry manager pack inside . because grid is already managing it's content windows}

test packgrid-3.4 {stealing slave} -setup {
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 . which already has slaves managed by pack}
} -result {cannot use geometry manager grid inside . because pack is already managing it's content windows}

test packgrid-4.1 {slave stolen after master destruction - bug [aa7679685e]} -setup {
test packgrid-4.1 {content stolen after container destruction - bug [aa7679685e]} -setup {
    frame .f
    button .b -text hello
} -body {
    pack .f
    grid .b -in .f
    destroy .f
    set res [winfo manager .b]
    # shall not crash
    pack .b
    set res
} -cleanup {
    destroy .b
} -result {}

test packgrid-4.2 {slave stolen after master destruction - bug [aa7679685e]} -setup {
test packgrid-4.2 {content stolen after container destruction - bug [aa7679685e]} -setup {
    frame .f
    button .b -text hello
} -body {
    pack .f
    pack .b -in .f
    destroy .f
    set res [winfo manager .b]

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 (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

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







-
+










-
+







    set result [list [winfo width .p.f]]
    .p.f configure -width 30
    update
    lappend result [winfo width .p.f]
} -cleanup {
	deleteWindows
} -result [list 20 20]
test panedwindow-12.7 {horizontal panedwindow reqheight is max slave height} -setup {
test panedwindow-12.7 {horizontal panedwindow reqheight is max pane height} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .p.f -width 20 -height 20] [frame .p.f2 -width 20 -height 20]
    set result [winfo reqheight .p]
    .p.f config -height 40
    lappend result [winfo reqheight .p]
} -cleanup {
	deleteWindows
} -result {20 40}
test panedwindow-12.8 {horizontal panedwindow reqheight is max slave height} -setup {
test panedwindow-12.8 {horizontal panedwindow reqheight is max pane height} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    foreach win {.p.f .p.f2} {.p add [frame $win -width 20 -height 20]}
    .p paneconfigure .p.f -height 15
    set result [winfo reqheight .p]
    .p.f config -height 40
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
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







-
+











-
+







    set result [list [winfo height .p.f]]
    .p.f configure -height 30
    update
    lappend result [winfo height .p.f]
} -cleanup {
	deleteWindows
} -result [list 20 20]
test panedwindow-12.12 {vertical panedwindow reqwidth is max slave width} -setup {
test panedwindow-12.12 {vertical panedwindow reqwidth is max pane width} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .p.f -width 20 -height 20] [frame .p.f2 -width 20 -height 20]
    set result [winfo reqwidth .p]
    .p.f config -width 40
    lappend result [winfo reqwidth .p]
} -cleanup {
	deleteWindows
} -result {20 40}
test panedwindow-12.13 {vertical panedwindow reqwidth is max slave width} -setup {
test panedwindow-12.13 {vertical panedwindow reqwidth is max pane width} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    foreach win {.p.f .p.f2} {.p add [frame $win -width 20 -height 20]}
    .p paneconfigure .p.f -width 15
    set result [winfo reqwidth .p]
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
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







-
+










-
+



-
+







} -result [list 10 10]


test panedwindow-13.1 {PanestructureProc, widget yields managements} -setup {
	deleteWindows
} -body {
    # Check that the panedwindow correctly yields geometry management of
    # a slave when the slave is destroyed.
    # 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 {PanedWindowLostSlaveProc, widget yields management} -setup {
test panedwindow-13.2 {PanedWindowLostPaneProc, widget yields management} -setup {
	deleteWindows
} -body {
    # Check that the paned window correctly yields geometry management of
    # a slave when some other geometry manager steals the slave from us.
    # a pane when some other geometry manager steals the pane from us.

    # This test should not cause a core dump, and it should not cause a
    # memory leak.
    panedwindow .p
    .p add [button .b]
    pack .p
    update
2237
2238
2239
2240
2241
2242
2243
2244

2245
2246
2247

2248
2249
2250
2251
2252
2253
2254
2237
2238
2239
2240
2241
2242
2243

2244
2245
2246

2247
2248
2249
2250
2251
2252
2253
2254







-
+


-
+







    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .p paneconfigure .f3 -width 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
} -cleanup {
	deleteWindows
} -result [list [list 60 60] [list 80 60]]

test panedwindow-19.7 {ComputeGeometry, one slave, reqsize set properly} -setup {
test panedwindow-19.7 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 0 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{20 0} {40 0}}

test panedwindow-19.10 {ComputeGeometry/ArrangePanes, slave coords} -setup {
test panedwindow-19.10 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{11 3 20 20} {53 3 20 20} {95 3 20 20}}

test panedwindow-19.11 {ComputeGeometry, one slave, vertical} -setup {
test panedwindow-19.11 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -orient vertical -sashwidth 0 -handlesize 6 \
        -showhandle 0
    .p add [frame .f -width 20 -height 20 -bg red] -pady 0 \
                    -sticky ""
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{0 20} {0 40}}

test panedwindow-19.14 {ComputeGeometry/ArrangePanes, slave coords, vert} -setup {
test panedwindow-19.14 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{3 11 20 20} {3 53 20 20} {3 95 20 20}}
test panedwindow-19.15 {ComputeGeometry, one slave, reqsize set properly} -setup {
test panedwindow-19.15 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 1 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{23 0} {49 0}}

test panedwindow-19.18 {ComputeGeometry/ArrangePanes, slave coords} -setup {
test panedwindow-19.18 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{11 3 20 20} {59 3 20 20} {107 3 20 20}}

test panedwindow-19.19 {ComputeGeometry, one slave, vertical} -setup {
test panedwindow-19.19 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -orient vertical -sashwidth 0 -handlesize 6 \
        -showhandle 1
    .p add [frame .f -width 20 -height 20 -bg red] -pady 1 \
                    -sticky ""
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{0 23} {0 49}}

test panedwindow-19.22 {ComputeGeometry/ArrangePanes, slave coords, vert} -setup {
test panedwindow-19.22 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{3 11 20 20} {3 59 20 20} {3 107 20 20}}
test panedwindow-19.23 {ComputeGeometry, one slave, reqsize set properly} -setup {
test panedwindow-19.23 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 0 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{20 0} {43 0}}

test panedwindow-19.26 {ComputeGeometry/ArrangePanes, slave coords} -setup {
test panedwindow-19.26 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{11 3 20 20} {56 3 20 20} {101 3 20 20}}

test panedwindow-19.27 {ComputeGeometry, one slave, vertical} -setup {
test panedwindow-19.27 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -orient vertical -sashwidth 3 -handlesize 6 \
        -showhandle 0
    .p add [frame .f -width 20 -height 20 -bg red] -pady 0 \
                    -sticky ""
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{0 20} {0 43}}

test panedwindow-19.30 {ComputeGeometry/ArrangePanes, slave coords, vert} -setup {
test panedwindow-19.30 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{3 11 20 20} {3 56 20 20} {3 101 20 20}}
test panedwindow-19.31 {ComputeGeometry, one slave, reqsize set properly} -setup {
test panedwindow-19.31 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 1 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{21 0} {47 0}}

test panedwindow-19.34 {ComputeGeometry/ArrangePanes, slave coords} -setup {
test panedwindow-19.34 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{11 3 20 20} {59 3 20 20} {107 3 20 20}}

test panedwindow-19.35 {ComputeGeometry, one slave, vertical} -setup {
test panedwindow-19.35 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -orient vertical -sashwidth 3 -handlesize 6 \
        -showhandle 1
    .p add [frame .f -width 20 -height 20 -bg red] -pady 1 \
                    -sticky ""
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{0 21} {0 47}}

test panedwindow-19.38 {ComputeGeometry/ArrangePanes, slave coords, vert} -setup {
test panedwindow-19.38 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{3 11 20 20} {3 59 20 20} {3 107 20 20}}
test panedwindow-19.39 {ComputeGeometry, one slave, reqsize set properly} -setup {
test panedwindow-19.39 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 0 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{25 0} {55 0}}

test panedwindow-19.42 {ComputeGeometry/ArrangePanes, slave coords} -setup {
test panedwindow-19.42 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{11 3 20 20} {63 3 20 20} {115 3 20 20}}

test panedwindow-19.43 {ComputeGeometry, one slave, vertical} -setup {
test panedwindow-19.43 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -orient vertical -sashwidth 0 -handlesize 6 \
        -showhandle 0
    .p add [frame .f -width 20 -height 20 -bg red] -pady 0 \
                    -sticky ""
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{0 25} {0 55}}

test panedwindow-19.46 {ComputeGeometry/ArrangePanes, slave coords, vert} -setup {
test panedwindow-19.46 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{3 11 20 20} {3 63 20 20} {3 115 20 20}}
test panedwindow-19.47 {ComputeGeometry, one slave, reqsize set properly} -setup {
test panedwindow-19.47 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 1 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{28 0} {64 0}}

test panedwindow-19.50 {ComputeGeometry/ArrangePanes, slave coords} -setup {
test panedwindow-19.50 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{11 3 20 20} {69 3 20 20} {127 3 20 20}}

test panedwindow-19.51 {ComputeGeometry, one slave, vertical} -setup {
test panedwindow-19.51 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -orient vertical -sashwidth 0 -handlesize 6 \
        -showhandle 1
    .p add [frame .f -width 20 -height 20 -bg red] -pady 1 \
                    -sticky ""
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{0 28} {0 64}}

test panedwindow-19.54 {ComputeGeometry/ArrangePanes, slave coords, vert} -setup {
test panedwindow-19.54 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{3 11 20 20} {3 69 20 20} {3 127 20 20}}
test panedwindow-19.55 {ComputeGeometry, one slave, reqsize set properly} -setup {
test panedwindow-19.55 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 0 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{25 0} {58 0}}

test panedwindow-19.58 {ComputeGeometry/ArrangePanes, slave coords} -setup {
test panedwindow-19.58 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{11 3 20 20} {66 3 20 20} {121 3 20 20}}

test panedwindow-19.59 {ComputeGeometry, one slave, vertical} -setup {
test panedwindow-19.59 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -orient vertical -sashwidth 3 -handlesize 6 \
        -showhandle 0
    .p add [frame .f -width 20 -height 20 -bg red] -pady 0 \
                    -sticky ""
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{0 25} {0 58}}

test panedwindow-19.62 {ComputeGeometry/ArrangePanes, slave coords, vert} -setup {
test panedwindow-19.62 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{3 11 20 20} {3 66 20 20} {3 121 20 20}}
test panedwindow-19.63 {ComputeGeometry, one slave, reqsize set properly} -setup {
test panedwindow-19.63 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 1 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{26 0} {62 0}}

test panedwindow-19.66 {ComputeGeometry/ArrangePanes, slave coords} -setup {
test panedwindow-19.66 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{11 3 20 20} {69 3 20 20} {127 3 20 20}}

test panedwindow-19.67 {ComputeGeometry, one slave, vertical} -setup {
test panedwindow-19.67 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -orient vertical -sashwidth 3 -handlesize 6 \
        -showhandle 1
    .p add [frame .f -width 20 -height 20 -bg red] -pady 1 \
                    -sticky ""
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{0 26} {0 62}}

test panedwindow-19.70 {ComputeGeometry/ArrangePanes, slave coords, vert} -setup {
test panedwindow-19.70 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{3 11 20 20} {3 69 20 20} {3 127 20 20}}
test panedwindow-19.71 {ComputeGeometry, one slave, reqsize set properly} -setup {
test panedwindow-19.71 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 0 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{22 2} {42 2}}

test panedwindow-19.74 {ComputeGeometry/ArrangePanes, slave coords} -setup {
test panedwindow-19.74 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{13 5 20 20} {55 5 20 20} {97 5 20 20}}

test panedwindow-19.75 {ComputeGeometry, one slave, vertical} -setup {
test panedwindow-19.75 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -orient vertical -sashwidth 0 -handlesize 6 \
        -showhandle 0
    .p add [frame .f -width 20 -height 20 -bg red] -pady 0 \
                    -sticky ""
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{2 22} {2 42}}

test panedwindow-19.78 {ComputeGeometry/ArrangePanes, slave coords, vert} -setup {
test panedwindow-19.78 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{5 13 20 20} {5 55 20 20} {5 97 20 20}}
test panedwindow-19.79 {ComputeGeometry, one slave, reqsize set properly} -setup {
test panedwindow-19.79 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 1 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{25 2} {51 2}}

test panedwindow-19.82 {ComputeGeometry/ArrangePanes, slave coords} -setup {
test panedwindow-19.82 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{13 5 20 20} {61 5 20 20} {109 5 20 20}}

test panedwindow-19.83 {ComputeGeometry, one slave, vertical} -setup {
test panedwindow-19.83 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -orient vertical -sashwidth 0 -handlesize 6 \
        -showhandle 1
    .p add [frame .f -width 20 -height 20 -bg red] -pady 1 \
                    -sticky ""
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{2 25} {2 51}}

test panedwindow-19.86 {ComputeGeometry/ArrangePanes, slave coords, vert} -setup {
test panedwindow-19.86 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 0 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{5 13 20 20} {5 61 20 20} {5 109 20 20}}
test panedwindow-19.87 {ComputeGeometry, one slave, reqsize set properly} -setup {
test panedwindow-19.87 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 0 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{22 2} {45 2}}

test panedwindow-19.90 {ComputeGeometry/ArrangePanes, slave coords} -setup {
test panedwindow-19.90 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{13 5 20 20} {58 5 20 20} {103 5 20 20}}

test panedwindow-19.91 {ComputeGeometry, one slave, vertical} -setup {
test panedwindow-19.91 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -orient vertical -sashwidth 3 -handlesize 6 \
        -showhandle 0
    .p add [frame .f -width 20 -height 20 -bg red] -pady 0 \
                    -sticky ""
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{2 22} {2 45}}

test panedwindow-19.94 {ComputeGeometry/ArrangePanes, slave coords, vert} -setup {
test panedwindow-19.94 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{5 13 20 20} {5 58 20 20} {5 103 20 20}}
test panedwindow-19.95 {ComputeGeometry, one slave, reqsize set properly} -setup {
test panedwindow-19.95 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 1 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{23 2} {49 2}}

test panedwindow-19.98 {ComputeGeometry/ArrangePanes, slave coords} -setup {
test panedwindow-19.98 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{13 5 20 20} {61 5 20 20} {109 5 20 20}}

test panedwindow-19.99 {ComputeGeometry, one slave, vertical} -setup {
test panedwindow-19.99 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -orient vertical -sashwidth 3 -handlesize 6 \
        -showhandle 1
    .p add [frame .f -width 20 -height 20 -bg red] -pady 1 \
                    -sticky ""
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{2 23} {2 49}}

test panedwindow-19.102 {ComputeGeometry/ArrangePanes, slave coords, vert} -setup {
test panedwindow-19.102 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 0 \
        -sashwidth 3 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{5 13 20 20} {5 61 20 20} {5 109 20 20}}
test panedwindow-19.103 {ComputeGeometry, one slave, reqsize set properly} -setup {
test panedwindow-19.103 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 0 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{27 2} {57 2}}

test panedwindow-19.106 {ComputeGeometry/ArrangePanes, slave coords} -setup {
test panedwindow-19.106 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{13 5 20 20} {65 5 20 20} {117 5 20 20}}

test panedwindow-19.107 {ComputeGeometry, one slave, vertical} -setup {
test panedwindow-19.107 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -orient vertical -sashwidth 0 -handlesize 6 \
        -showhandle 0
    .p add [frame .f -width 20 -height 20 -bg red] -pady 0 \
                    -sticky ""
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{2 27} {2 57}}

test panedwindow-19.110 {ComputeGeometry/ArrangePanes, slave coords, vert} -setup {
test panedwindow-19.110 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{5 13 20 20} {5 65 20 20} {5 117 20 20}}
test panedwindow-19.111 {ComputeGeometry, one slave, reqsize set properly} -setup {
test panedwindow-19.111 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 1 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{30 2} {66 2}}

test panedwindow-19.114 {ComputeGeometry/ArrangePanes, slave coords} -setup {
test panedwindow-19.114 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{13 5 20 20} {71 5 20 20} {129 5 20 20}}

test panedwindow-19.115 {ComputeGeometry, one slave, vertical} -setup {
test panedwindow-19.115 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -orient vertical -sashwidth 0 -handlesize 6 \
        -showhandle 1
    .p add [frame .f -width 20 -height 20 -bg red] -pady 1 \
                    -sticky ""
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{2 30} {2 66}}

test panedwindow-19.118 {ComputeGeometry/ArrangePanes, slave coords, vert} -setup {
test panedwindow-19.118 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 0 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{5 13 20 20} {5 71 20 20} {5 129 20 20}}
test panedwindow-19.119 {ComputeGeometry, one slave, reqsize set properly} -setup {
test panedwindow-19.119 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 0 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{27 2} {60 2}}

test panedwindow-19.122 {ComputeGeometry/ArrangePanes, slave coords} -setup {
test panedwindow-19.122 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 0
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{13 5 20 20} {68 5 20 20} {123 5 20 20}}

test panedwindow-19.123 {ComputeGeometry, one slave, vertical} -setup {
test panedwindow-19.123 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -orient vertical -sashwidth 3 -handlesize 6 \
        -showhandle 0
    .p add [frame .f -width 20 -height 20 -bg red] -pady 0 \
                    -sticky ""
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{2 27} {2 60}}

test panedwindow-19.126 {ComputeGeometry/ArrangePanes, slave coords, vert} -setup {
test panedwindow-19.126 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 0 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 11 -padx 3
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
        }
    return $result
} -cleanup {
    deleteWindows
} -result {{5 13 20 20} {5 68 20 20} {5 123 20 20}}
test panedwindow-19.127 {ComputeGeometry, one slave, reqsize set properly} -setup {
test panedwindow-19.127 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    .p add [frame .p.f -width 20 -height 20 -bg red] -padx 1 -sticky ""
    list [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
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
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







-
+




















-
+


-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{28 2} {64 2}}

test panedwindow-19.130 {ComputeGeometry/ArrangePanes, slave coords} -setup {
test panedwindow-19.130 {ComputeGeometry/ArrangePanes, pane coords} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 1
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
            -sticky nsew -pady 3 -padx 11
    }
    pack .p
    update
    set result {}
    foreach w {.p.f1 .p.f2 .p.f3} {
        lappend result [list [winfo x $w] [winfo y $w] \
            [winfo width $w] [winfo height $w]]
    }
    return $result
} -cleanup {
    deleteWindows
} -result {{13 5 20 20} {71 5 20 20} {129 5 20 20}}

test panedwindow-19.131 {ComputeGeometry, one slave, vertical} -setup {
test panedwindow-19.131 {ComputeGeometry, one pane, vertical} -setup {
    deleteWindows
} -body {
    # With just one slave, sashpad and sashwidth should not
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
    # ever be drawn.
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -orient vertical -sashwidth 3 -handlesize 6 \
        -showhandle 1
    .p add [frame .f -width 20 -height 20 -bg red] -pady 1 \
                    -sticky ""
4280
4281
4282
4283
4284
4285
4286
4287

4288
4289
4290
4291
4292
4293
4294
4280
4281
4282
4283
4284
4285
4286

4287
4288
4289
4290
4291
4292
4293
4294







-
+







                            -sticky ""
    }
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{2 28} {2 64}}

test panedwindow-19.134 {ComputeGeometry/ArrangePanes, slave coords, vert} -setup {
test panedwindow-19.134 {ComputeGeometry/ArrangePanes, pane coords, vert} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 2 -sashpad 5 \
        -sashwidth 3 -handlesize 6 -showhandle 1 \
        -orient vertical
    foreach w {.p.f1 .p.f2 .p.f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] \
4313
4314
4315
4316
4317
4318
4319
4320

4321
4322
4323
4324
4325
4326
4327
4313
4314
4315
4316
4317
4318
4319

4320
4321
4322
4323
4324
4325
4326
4327







-
+







    panedwindow .p
    .p add [frame .f -width 20 -height 20 -bg blue]
    destroy .f
    .p panes
} -cleanup {
	deleteWindows
} -result {}
test panedwindow-20.2 {destroyed slave causes geometry recomputation} -setup {
test panedwindow-20.2 {destroyed pane causes geometry recomputation} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red]
    destroy .f
    winfo reqwidth .p
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
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







-
+












-
+







	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 slave geometry changes} -setup {
test panedwindow-22.1 {PanedWindowReqProc, react to pane geometry changes} -setup {
	deleteWindows
} -body {
    # Basically just want to make sure that the PanedWindowReqProc is called
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 40 -bg red]
    set result [winfo reqheight .p]
    .f1 configure -height 80
    lappend result [winfo reqheight .p]
} -cleanup {
	deleteWindows
} -result {40 80}
test panedwindow-22.2 {PanedWindowReqProc, react to slave geometry changes} -setup {
test panedwindow-22.2 {PanedWindowReqProc, react to pane geometry changes} -setup {
	deleteWindows
} -body {
    panedwindow .p -orient horizontal -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 10] [frame .f2 -width 10]
    set result [winfo reqwidth .p]
    .f1 configure -width 20
    lappend result [winfo reqwidth .p]
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
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







-
+














-
+








    .p add .a .b .c
    .p add .d .b -before .a
    .p panes
} -cleanup {
	deleteWindows
} -result {.d .b .a .c}
test panedwindow-23.22 {ConfigurePanes, slave specified multiple times} -setup {
test panedwindow-23.22 {ConfigurePanes, pane specified multiple times} -setup {
	deleteWindows
} -body {
    # This test should not cause a core dump

    panedwindow .p
    button .a
    button .b
    button .c

    .p add .a .a .b .c
    .p panes
} -cleanup {
	deleteWindows
} -result {.a .b .c}
test panedwindow-23.23 {ConfigurePanes, slave specified multiple times} -setup {
test panedwindow-23.23 {ConfigurePanes, pane specified multiple times} -setup {
	deleteWindows
} -body {
    # This test should not cause a core dump

    panedwindow .p
    button .a
    button .b
5142
5143
5144
5145
5146
5147
5148
5149

5150
5151
5152
5153
5154
5155
5156
5142
5143
5144
5145
5146
5147
5148

5149
5150
5151
5152
5153
5154
5155
5156







-
+







	    .p add [button $w]
    }
    foreach w {.a .b .c .d .e .f .g .h .i .j .k .l .m .n .o .p .q .r .s .t} {
	    destroy $w
    }
    set result {}
} -result {}
test panedwindow-25.2 {UnmapNotify and MapNotify events are propagated to slaves} -setup {
test panedwindow-25.2 {UnmapNotify and MapNotify events are propagated to panes} -setup {
    deleteWindows
} -body {
    panedwindow .pw
    .pw add [button .pw.b]
    pack .pw
    update
    set result [winfo ismapped .pw.b]

Changes to 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
1
2
3
4
5
6
7




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

23
24
25
26
27
28
29
30







-
-
-
-
+
+
+
+









+
+
-
+







# -*- 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 (c) 1991-1993 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright (c) 2017 Stuart Cassoff <[email protected]>
# Copyright © 1991-1993 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# Copyright © 2017 Stuart Cassoff <[email protected]>
#
# 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} nonwin {
test pkgconfig-1.1 {query keys} {nonwin 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 \
]

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
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 is a Tcl script to test out the "place" command.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1995 Sun Microsystems, Inc.
# Copyright © 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(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
wm geom .t +0+0
49
50
51
52
53
54
55
56

57
58
59

60
61
62
63
64
65
66

67
68
69
70
71
72
73
74
75
76
77

78
79
80

81
82
83
84
85
86
87

88
89
90
91
92
93
94
95
96
97
98

99
100
101
102
103


104
105
106
107
108
109
110

111
112
113
114
115
116


117
118
119
120
121


122
123
124
125

126
127
128
129
130
131

132
133
134
135
136
137
138
139
140

141
142

143
144
145

146
147
148
149
150
151
152

153
154
155
156
157
158
159
160
161
162

163
164
165

166
167
168
169
170
171
172

173
174
175
176
177
178
179
52
53
54
55
56
57
58

59
60
61

62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79

80
81
82

83
84
85
86
87
88
89

90
91
92
93
94
95
96
97
98
99
100

101
102
103
104


105
106
107
108
109
110
111
112

113
114
115
116
117


118
119
120
121
122


123
124
125
126
127

128
129
130
131
132
133

134
135
136
137
138
139
140
141
142

143
144

145
146
147

148
149
150
151
152
153
154

155
156
157
158
159
160
161
162
163
164

165
166
167

168
169
170
171
172
173
174

175
176
177
178
179
180
181
182







-
+


-
+






-
+










-
+


-
+






-
+










-
+



-
-
+
+






-
+




-
-
+
+



-
-
+
+



-
+





-
+








-
+

-
+


-
+






-
+









-
+


-
+






-
+







        -bordermode ignore
    place info .t.f2
} -cleanup {
    destroy ".t.a.b"
} -result {-in {.t.a b} -x 1 -relx 0.2 -y 2 -rely 0.2 -width {} -relwidth 0.3 -height 4 -relheight {} -anchor w -bordermode ignore}


test place-2.1 {ConfigureSlave procedure, -height option} -body {
test place-2.1 {ConfigureContent procedure, -height option} -body {
    place .t.f2 -height abcd
} -returnCodes error -result {bad screen distance "abcd"}
test place-2.2 {ConfigureSlave procedure, -height option} -setup {
test place-2.2 {ConfigureContent procedure, -height option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -height 40
    update
    winfo height .t.f2
} -result 40
test place-2.3 {ConfigureSlave procedure, -height option} -setup {
test place-2.3 {ConfigureContent procedure, -height option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -height 120
    update
    place .t.f2 -height {}
    update
    winfo height .t.f2
} -result 60


test place-3.1 {ConfigureSlave procedure, -relheight option} -body {
test place-3.1 {ConfigureContent procedure, -relheight option} -body {
    place .t.f2 -relheight abcd
} -returnCodes error -result {expected floating-point number but got "abcd"}
test place-3.2 {ConfigureSlave procedure, -relheight option} -setup {
test place-3.2 {ConfigureContent procedure, -relheight option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -relheight .5
    update
    winfo height .t.f2
} -result 40
test place-3.3 {ConfigureSlave procedure, -relheight option} -setup {
test place-3.3 {ConfigureContent procedure, -relheight option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -relheight .8
    update
    place .t.f2 -relheight {}
    update
    winfo height .t.f2
} -result 60


test place-4.1 {ConfigureSlave procedure, bad -in options} -setup {
test place-4.1 {ConfigureContent procedure, bad -in options} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f2
} -returnCodes error -result {can't place .t.f2 relative to itself}
test place-4.2 {ConfigureSlave procedure, bad -in option} -setup {
} -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 {ConfigureSlave procedure, bad -in option} -setup {
test place-4.3 {ConfigureContent procedure, bad -in option} -setup {
    place forget .t.f2
} -body {
    winfo manager .t.f2
    place .t.f2 -in .t.f2
} -returnCodes error -result {can't place .t.f2 relative to itself}
test place-4.4 {ConfigureSlave procedure, bad -in option} -setup {
} -returnCodes error -result {can't place ".t.f2" relative to itself}
test place-4.4 {ConfigureContent procedure, bad -in option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .
} -returnCodes error -result {can't place .t.f2 relative to .}
test place-4.5 {ConfigureSlave procedure, bad -in option} -setup {
} -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 {ConfigureSlave procedure, -relwidth option} -body {
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 {ConfigureSlave procedure, -relwidth option} -setup {
test place-5.2 {ConfigureContent procedure, -relwidth option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -relwidth .5
    update
    winfo width .t.f2
} -result 75
test place-5.3 {ConfigureSlave procedure, -relwidth option} -setup {
test place-5.3 {ConfigureContent procedure, -relwidth option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -relwidth .8
    update
    place .t.f2 -relwidth {}
    update
    winfo width .t.f2
} -result 30

test place-6.1 {ConfigureSlave procedure, -width option} -body {
test place-6.1 {ConfigureContent procedure, -width option} -body {
    place .t.f2 -width abcd
} -returnCodes error -result {bad screen distance "abcd"}
test place-6.2 {ConfigureSlave procedure, -width option} -setup {
test place-6.2 {ConfigureContent procedure, -width option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -width 100
    update
    winfo width .t.f2
} -result 100
test place-6.3 {ConfigureSlave procedure, -width option} -setup {
test place-6.3 {ConfigureContent procedure, -width option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -width 120
    update
    place .t.f2 -width {}
    update
    winfo width .t.f2
254
255
256
257
258
259
260



261
262







263
264
265
266
267

268
269
270
271
272
273

274
275
276

277
278
279

280
281

282
283
284
285

286
287
288
289
290
291

292
293
294

295
296
297
298
299
300
301
257
258
259
260
261
262
263
264
265
266


267
268
269
270
271
272
273
274
275
276
277

278
279
280

281
282

283
284
285

286
287
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] ne "aqua"} {
    proc placeUpdate {} {
	update

test place-8.1 {MasterStructureProc, mapping and unmapping slaves} -setup {
    }
} else {
    proc placeUpdate {} {
    }
}

test place-8.1 {PlaceStructureProc, mapping and unmapping content} -constraints {failsOnUbuntu failsOnXQuarz} -setup {
    place forget .t.f2
    place forget .t.f
} -body {
    place .t.f2 -relx 1.0 -rely 1.0 -anchor sw
    update
    update idletasks
    set result [winfo ismapped .t.f2]
    wm iconify .t
    update
    lappend result [winfo ismapped .t.f2]
    place .t.f2 -x 40 -y 30 -relx 0 -rely 0 -anchor nw
    update
    update idletasks
    lappend result [winfo x .t.f2] [winfo y .t.f2] [winfo ismapped .t.f2]
    wm deiconify .t
    update
    placeUpdate
    lappend result [winfo ismapped .t.f2]
} -result {1 0 40 30 0 1}
test place-8.2 {MasterStructureProc, mapping and unmapping slaves} -setup {
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
    update idletasks
    set result [winfo ismapped .t.f2]
    wm iconify .t
    update
    lappend result [winfo ismapped .t.f2]
    place .t.f2 -x 40 -y 30 -relx 0 -rely 0 -anchor nw
    update
    update idletasks
    lappend result [winfo x .t.f2] [winfo y .t.f2] [winfo ismapped .t.f2]
    wm deiconify .t
    update
    placeUpdate
    lappend result [winfo ismapped .t.f2]
} -result {1 0 42 32 0 1}
destroy .t


test place-9.1 {PlaceObjCmd} -body {
    place
318
319
320
321
322
323
324
325

326
327
328
329
330
331
332
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, forget, info, or slaves}
} -returnCodes error -result {bad option "badopt": must be configure, content, forget, or info}
test place-9.6 {PlaceObjCmd, configure errors} -setup {
    destroy .foo
} -body {
    frame .foo
    place configure .foo
} -cleanup {
    destroy .foo
369
370
371
372
373
374
375
376

377
378
379
380

381
382
383

384
385
386

387
388
389
390
391
392
393
394

395
396
397
398
399
400
401
402

403
404
405
406
407
408
409
410

411
412
413
414
415
416
417
418
419
420

421
422
423
424

425
426
427
428

429
430
431
432
433
434

435
436
437
438
439
440
441
379
380
381
382
383
384
385

386
387
388
389

390
391
392

393
394
395

396
397
398
399
400
401
402
403

404
405
406
407
408
409
410
411

412
413
414
415
416
417
418
419

420
421
422
423
424
425
426
427
428
429

430
431
432
433

434
435
436
437

438
439
440
441
442
443

444
445
446
447
448
449
450
451







-
+



-
+


-
+


-
+







-
+







-
+







-
+









-
+



-
+



-
+





-
+







    destroy .foo
} -body {
    frame .foo
    place info .foo bar
} -cleanup {
    destroy .foo
} -returnCodes error -result {wrong # args: should be "place info pathName"}
test place-9.12 {PlaceObjCmd, slaves errors} -setup {
test place-9.12 {PlaceObjCmd, content errors} -setup {
    destroy .foo
} -body {
    frame .foo
    place slaves .foo bar
    place content .foo bar
} -cleanup {
    destroy .foo
} -returnCodes error -result {wrong # args: should be "place slaves pathName"}
} -returnCodes error -result {wrong # args: should be "place content pathName"}


test place-10.1 {ConfigureSlave} -setup {
test place-10.1 {ConfigureContent} -setup {
    destroy .foo
} -body {
    frame .foo
    place .foo -badopt
} -cleanup {
    destroy .foo
} -returnCodes error -result {unknown option "-badopt"}
test place-10.2 {ConfigureSlave} -setup {
test place-10.2 {ConfigureContent} -setup {
    destroy .foo
} -body {
    frame .foo
    place .foo -anchor
} -cleanup {
    destroy .foo
} -returnCodes error -result {value for "-anchor" missing}
test place-10.3 {ConfigureSlave} -setup {
test place-10.3 {ConfigureContent} -setup {
    destroy .foo
} -body {
    frame .foo
    place .foo -bordermode j
} -cleanup {
    destroy .foo
} -returnCodes error -result {bad bordermode "j": must be inside, outside, or ignore}
test place-10.4 {ConfigureSlave} -setup {
test place-10.4 {ConfigureContent} -setup {
    destroy .foo
} -body {
    frame .foo
    place configure .foo -x 0 -y
} -cleanup {
    destroy .foo
} -returnCodes error -result {value for "-y" missing}


test place-11.1 {PlaceObjCmd, slaves command} -setup {
test place-11.1 {PlaceObjCmd, content command} -setup {
    destroy .foo
} -body {
    frame .foo
    place slaves .foo
    place content .foo
} -cleanup {
    destroy .foo
} -result {}
test place-11.2 {PlaceObjCmd, slaves command} -setup {
test place-11.2 {PlaceObjCmd, content command} -setup {
    destroy .foo .bar
} -body {
    frame .foo
    frame .bar
    place .bar -in .foo
    place slaves .foo
    place content .foo
} -cleanup {
    destroy .foo .bar
} -result [list .bar]


test place-12.1 {PlaceObjCmd, forget command} -setup {
    destroy .foo
489
490
491
492
493
494
495
496

497
498
499
500
501


502
503
504



505
506
507
508
509




510
511
512
513
514
515
516
499
500
501
502
503
504
505

506
507
508
509


510
511
512


513
514
515
516




517
518
519
520
521
522
523
524
525
526
527







-
+



-
-
+
+

-
-
+
+
+

-
-
-
-
+
+
+
+







                set end [getbytes]
            }
            lappend res [expr {$end - $tmp}]
        }
        return $res
    }
} -body {
    # Test all manners of forgetting a slave
    # 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
1
2
3
4
5



6
7
8
9
10
11
12
13
14
15





-
-
-
+
+
+







# This file is a Tcl script to test out Tk's "raise" and
# "lower" commands, plus associated code to manage window
# stacking order.  It is organized in the standard fashion
# for Tcl tests.
#
# Copyright (c) 1993-1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1993-1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 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/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 (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44





45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63













64





65
66
67


68
69
70
71
72
73
74
29
30
31
32
33
34
35

36








37
38
39
40
41



















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

55
56
57
58
59
60


61
62
63
64
65
66
67
68
69







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

-
-
+
+








## it indicates that something went wrong sourcing tk.tcl.
## Ensure that any changes that occurred to tk.tcl will work or are properly
## prevented in a safe interpreter.  -- hobbs

# The set of hidden commands is platform dependent:

set hidden_cmds {bell cd clipboard encoding exec exit fconfigure}
set hidden_cmds [list bell cd clipboard encoding exec exit \
lappend hidden_cmds {*}[apply {{} {
    if {[package vsatisfies [package provide Tcl] 8.7-]} {
	lappend result file
    }
    lappend result glob grab load menu open pwd selection socket source tcl:encoding:dirs
    if {[package vsatisfies [package provide Tcl] 8.7-]} {
	lappend result tcl:encoding:system
    }
	fconfigure glob grab load menu open pwd selection \
	socket source toplevel unload wm]
if {[package vsatisfies [package provide Tcl] 8.6.7-]} {
    lappend hidden_cmds tcl:encoding:dirs
}
    lappend result toplevel unload wm
    foreach cmd {
	atime attributes copy delete dirname executable exists extension
	isdirectory isfile link lstat mkdir mtime nativename normalize owned
	readable readlink rename rootname size stat tail tempdir tempfile type
	volumes writable
    } {lappend result tcl:file:$cmd}
    if {[package vsatisfies [package provide Tcl] 8.7-]} {
	foreach cmd {
	    cmdtype nameofexecutable
	} {lappend result tcl:info:$cmd}
	foreach cmd {
	    autopurge list purge status
	} {lappend result tcl:process:$cmd}
	foreach cmd {
	    lmkimg lmkzip mkimg mkkey mkzip mount  mount_data unmount
	} {lappend result tcl:zipfs:$cmd}
    }
    return $result
if {[package vsatisfies [package provide Tcl] 8.7-]} {
    lappend hidden_cmds file tcl:encoding:system tcl:file:tempdir
    foreach cmd {
	cmdtype nameofexecutable
    } {lappend hidden_cmds tcl:info:$cmd}
    foreach cmd {
	autopurge list purge status
    } {lappend hidden_cmds tcl:process:$cmd}
    foreach cmd {
	lmkimg lmkzip mkimg mkkey mkzip mount  mount_data unmount
    } {lappend hidden_cmds tcl:zipfs:$cmd}
}
foreach cmd {
}}]
    atime attributes copy delete dirname executable exists extension
    isdirectory isfile link lstat mkdir mtime nativename normalize
    owned readable readlink rename rootname size stat tail tempfile
    type volumes writable
} {lappend hidden_cmds tcl:file:$cmd}
if {[tk windowingsystem] ne "x11"} {
    lappend hidden_cmds tk_chooseColor tk_chooseDirectory tk_getOpenFile \
	tk_getSaveFile tk_messageBox
    lappend hidden_cmds tk_chooseColor tk_chooseDirectory \
	tk_getOpenFile tk_getSaveFile tk_messageBox
}
if {[llength [info commands send]]} {
    lappend hidden_cmds send
}

set saveAutoPath $::auto_path
set auto_path [list [info library] $::tk_library]
198
199
200
201
202
203
204
205

206
207
208
209
210

211
212
213
214
215
216
217
193
194
195
196
197
198
199

200
201
202
203
204

205
206
207
208
209
210
211
212







-
+




-
+







    pack $w
    set i [safe::loadTk [safe::interpCreate] -use [winfo id $w]]
    interp eval $i {button .b -text "hello world!"; pack .b}
    safe::interpDelete $i
    destroy $w
} -result {}

test safe-5.1 {loading Tk in safe interps without master's clearance} -body {
test safe-5.1 {loading Tk in safe interps without parent's clearance} -body {
    set i [safe::interpCreate]
    interp eval $i {load {} Tk}
} -cleanup {
    safe::interpDelete $i
} -returnCodes error -result {not allowed}
} -returnCodes error -match glob -result {*not allowed}
test safe-5.2 {multi-level Tk loading with clearance} -setup {
    set safeParent [safe::interpCreate]
} -body {
    # No error shall occur in that test and no window shall remain at the end.
    set i [safe::interpCreate [list $safeParent x]]
    safe::loadTk $i
    interp eval $i {

Changes to tests/safePrimarySelection.test.

1
2
3
4
5
6



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



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

37
38
39
40
41

42
43
44
45
46
47
48
1
2
3



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18



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

36
37
38
39
40

41
42
43
44
45
46
47
48



-
-
-
+
+
+












-
-
-
+
+
+














-
+




-
+







# This file is a Tcl script to test entry widgets in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

# ------------------------------------------------------------------------------
# Tests that a Safe Base interpreter cannot write to the PRIMARY selection.
# ------------------------------------------------------------------------------
# - Tests 3.*, 6.* test that the fix for ticket de156e9efe implemented in branch
#   bug-de156e9efe has been applied and still works.  They test that a Safe Base
#   slave interpreter cannot write to the PRIMARY selection.
# - The other tests verify that the master interpreter and an unsafe slave CAN
#   write to the PRIMARY selection, and therefore that the test scripts
#   child interpreter cannot write to the PRIMARY selection.
# - The other tests verify that the parent interpreter and an child interpreter
#   CAN write to the PRIMARY selection, and therefore that the test scripts
#   themselves are valid.
# - A text, entry, ttk::entry, listbox, spinbox or ttk::spinbox widget can have
#   option -exportselection 1, meaning (in an unsafe interpreter) that a
#   selection made in one of these widgets is automatically written to the
#   PRIMARY selection.
# - A safe interpreter must not write to the PRIMARY selection.
# - The spinbox, ttk::spinbox are variants of entry, ttk::entry respectively.
# ------------------------------------------------------------------------------

namespace eval ::_test_tmp {}

# ------------------------------------------------------------------------------
#  Proc ::_test_tmp::unsafeInterp
# ------------------------------------------------------------------------------
# Command that creates an unsafe child interpreter and tries to load Tk.
# Command that creates an child interpreter and tries to load Tk.
# - This is necessary for loading Tk if the tests are done in the build
#   directory without installing Tk.  In that case the usual auto_path loading
#   mechanism cannot work because the tk binary is not where pkgIndex.tcl says
#   it is.
# - This command is not needed for Safe Base slaves because safe::loadTk does
# - This command is not needed for Safe Base children because safe::loadTk does
#   something similar and works correctly.
# - Based on scripts in winSend.test.
# ------------------------------------------------------------------------------

namespace eval ::_test_tmp {
    variable TkLoadCmd
}
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







-
+







    interp create $name
    $name eval [list set argv [list -name $name]]
    catch {{*}$TkLoadCmd $name}
}


set ::_test_tmp::script {
    package require Tk
    package require tk
    namespace eval ::_test_tmp {}

    proc ::_test_tmp::getPrimarySelection {} {
        if {[catch {::tk::GetSelection . PRIMARY} sel]} {
            set sel {}
        }
        return $sel
204
205
206
207
208
209
210
211

212
213
214
215


216
217
218
219
220
221
222
223
224
225
226
227


228
229
230
231
232
233
234
235
236
237
238
239


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


252
253
254
255
256
257
258
259
260
261
262
263


264
265
266
267
268
269
270
271
272
273
274
275


276
277
278
279
280
281
282
283
284
285
286
287


288
289
290
291
292
293
294
295
296
297
298
299


300
301
302
303
304
305
306
307
308
309
310
311


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


324
325
326
327
328
329
330
331
332
333
334
335


336
337
338
339

340
341
342
343
344
345
346
347
348
349
350
351
352


353
354
355
356

357
358
359
360
361
362
363
364
365
366
367
368
369


370
371
372
373

374
375
376
377
378
379
380
381
382
383
384
385
386


387
388
389
390

391
392
393
394
395
396
397
398
399
400
401
402
403


404
405
406
407

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


421
422
423
424

425
426
427
428
429
430
431
432
433
434
435
436
437


438
439
440
441

442
443
444
445
446
447
448
449
450
451
452
453
454


455
456
457
458

459
460
461
462
463
464
465
466
467
468
469
470
471


472
473
474
475

476
477
478
479
480
481
482
483
484
485
486
487
488


489
490
491
492

493
494
495
496
497
498
499
500
501
502
503
504
505


506
507
508
509
510

511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526


527
528
529
530
531

532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547


548
549
550
551
552

553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568


569
570
571
572
573

574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589


590
591
592
593
594

595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610


611
612
613
614
615

616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631


632
633
634
635
636

637
638
639
640
641
642
643
644
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
204
205
206
207
208
209
210

211
212
213


214
215
216
217
218
219
220
221
222
223
224
225


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


238
239
240
241
242
243
244
245
246
247
248
249


250
251
252
253
254
255
256
257
258
259
260
261


262
263
264
265
266
267
268
269
270
271
272
273


274
275
276
277
278
279
280
281
282
283
284
285


286
287
288
289
290
291
292
293
294
295
296
297


298
299
300
301
302
303
304
305
306
307
308
309


310
311
312
313
314
315
316
317
318
319
320
321


322
323
324
325
326
327
328
329
330
331
332
333


334
335
336
337
338

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


351
352
353
354
355

356
357
358
359
360
361
362
363
364
365
366
367


368
369
370
371
372

373
374
375
376
377
378
379
380
381
382
383
384


385
386
387
388
389

390
391
392
393
394
395
396
397
398
399
400
401


402
403
404
405
406

407
408
409
410
411
412
413
414
415
416
417
418


419
420
421
422
423

424
425
426
427
428
429
430
431
432
433
434
435


436
437
438
439
440

441
442
443
444
445
446
447
448
449
450
451
452


453
454
455
456
457

458
459
460
461
462
463
464
465
466
467
468
469


470
471
472
473
474

475
476
477
478
479
480
481
482
483
484
485
486


487
488
489
490
491

492
493
494
495
496
497
498
499
500
501
502
503


504
505
506
507
508
509

510
511
512
513
514
515
516
517
518
519
520
521
522
523
524


525
526
527
528
529
530

531
532
533
534
535
536
537
538
539
540
541
542
543
544
545


546
547
548
549
550
551

552
553
554
555
556
557
558
559
560
561
562
563
564
565
566


567
568
569
570
571
572

573
574
575
576
577
578
579
580
581
582
583
584
585
586
587


588
589
590
591
592
593

594
595
596
597
598
599
600
601
602
603
604
605
606
607
608


609
610
611
612
613
614

615
616
617
618
619
620
621
622
623
624
625
626
627
628
629


630
631
632
633
634
635

636
637
638
639
640
641
642
643
644
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







-
+


-
-
+
+










-
-
+
+










-
-
+
+










-
-
+
+










-
-
+
+










-
-
+
+










-
-
+
+










-
-
+
+










-
-
+
+










-
-
+
+










-
-
+
+



-
+











-
-
+
+



-
+











-
-
+
+



-
+











-
-
+
+



-
+











-
-
+
+



-
+











-
-
+
+



-
+











-
-
+
+



-
+











-
-
+
+



-
+











-
-
+
+



-
+











-
-
+
+



-
+











-
-
+
+




-
+














-
-
+
+




-
+














-
-
+
+




-
+














-
-
+
+




-
+














-
-
+
+




-
+














-
-
+
+




-
+














-
-
+
+




-
+














-
-
+
+




-
+














-
-
+
+




-
+














-
-
+
+




-
+














-
-
+
+










-
-
+
+










-
-
+
+










-
-
+
+










-
-
+
+










-
-
+
+










-
-
+
+










-
-
+
+










-
-
+
+










-
-
+
+










-
-
+
+



-
+











-
-
+
+



-
+











-
-
+
+



-
+











-
-
+
+



-
+











-
-
+
+



-
+











-
-
+
+



-
+











-
-
+
+



-
+











-
-
+
+



-
+











-
-
+
+



-
+











-
-
+
+



-
+











-
-
+
+




-
+














-
-
+
+




-
+














-
-
+
+




-
+














-
-
+
+




-
+














-
-
+
+




-
+














-
-
+
+




-
+














-
-
+
+




-
+














-
-
+
+




-
+














-
-
+
+




-
+














-
-
+
+




-
+







            update
            return
            # selects 3
        }
    }
}

# Do this once for the master interpreter.
# Do this once for the parent interpreter.
eval $::_test_tmp::script

test safePrimarySelection-1.1 {master interpreter, text, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-1.1 {parent interpreter, text, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    ::_test_tmp::tryText
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-1.2 {master interpreter, entry, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-1.2 {parent interpreter, entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    ::_test_tmp::tryEntry
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-1.3 {master interpreter, ttk::entry, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-1.3 {parent interpreter, ttk::entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    ::_test_tmp::tryTtkEntry
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-1.4 {master interpreter, listbox, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-1.4 {parent interpreter, listbox, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    ::_test_tmp::tryListbox
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-1.5 {master interpreter, spinbox as entry, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-1.5 {parent interpreter, spinbox as entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    ::_test_tmp::trySpinbox 1
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-1.6 {master interpreter, spinbox spun, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-1.6 {parent interpreter, spinbox spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    ::_test_tmp::trySpinbox 2
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result 2

test safePrimarySelection-1.7 {master interpreter, spinbox spun/selected/spun, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-1.7 {parent interpreter, spinbox spun/selected/spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    ::_test_tmp::trySpinbox 3
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result 3

test safePrimarySelection-1.8 {master interpreter, ttk::spinbox as entry, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-1.8 {parent interpreter, ttk::spinbox as entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    ::_test_tmp::tryTtkSpinbox 1
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-1.9 {master interpreter, ttk::spinbox spun, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-1.9 {parent interpreter, ttk::spinbox spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    ::_test_tmp::tryTtkSpinbox 2
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result 2

test safePrimarySelection-1.10 {master interpreter, ttk::spinbox spun/selected/spun, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-1.10 {parent interpreter, ttk::spinbox spun/selected/spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    ::_test_tmp::tryTtkSpinbox 3
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result 3

test safePrimarySelection-2.1 {unsafe slave interpreter, text, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-2.1 {child interpreter, text, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set int2 slave2
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryText
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-2.2 {unsafe slave interpreter, entry, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-2.2 {child interpreter, entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set int2 slave2
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryEntry
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-2.3 {unsafe slave interpreter, ttk::entry, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-2.3 {child interpreter, ttk::entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set int2 slave2
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkEntry
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-2.4 {unsafe slave interpreter, listbox, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-2.4 {child interpreter, listbox, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set int2 slave2
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryListbox
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-2.5 {unsafe slave interpreter, spinbox as entry, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-2.5 {child interpreter, spinbox as entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set int2 slave2
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 1
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-2.6 {unsafe slave interpreter, spinbox spun, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-2.6 {child interpreter, spinbox spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set int2 slave2
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 2
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result 2

test safePrimarySelection-2.7 {unsafe slave interpreter, spinbox spun/selected/spun, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-2.7 {child interpreter, spinbox spun/selected/spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set int2 slave2
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 3
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result 3

test safePrimarySelection-2.8 {unsafe slave interpreter, ttk::spinbox as entry, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-2.8 {child interpreter, ttk::spinbox as entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set int2 slave2
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 1
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-2.9 {unsafe slave interpreter, ttk::spinbox spun, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-2.9 {child interpreter, ttk::spinbox spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set int2 slave2
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 2
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result 2

test safePrimarySelection-2.10 {unsafe slave interpreter, ttk::spinbox spun/selected/spun, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-2.10 {child interpreter, ttk::spinbox spun/selected/spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set int2 slave2
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 3
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result 3

test safePrimarySelection-3.1 {IMPORTANT, safe slave interpreter, text, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-3.1 {IMPORTANT, safe interpreter, text, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 slave2
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryText
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {----}

test safePrimarySelection-3.2 {IMPORTANT, safe slave interpreter, entry, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-3.2 {IMPORTANT, safe interpreter, entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 slave2
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryEntry
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {----}

test safePrimarySelection-3.3 {IMPORTANT, safe slave interpreter, ttk::entry, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-3.3 {IMPORTANT, safe interpreter, ttk::entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 slave2
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkEntry
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {----}

test safePrimarySelection-3.4 {IMPORTANT, safe slave interpreter, listbox, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-3.4 {IMPORTANT, safe interpreter, listbox, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 slave2
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryListbox
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {----}

test safePrimarySelection-3.5 {IMPORTANT, safe slave interpreter, spinbox as entry, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-3.5 {IMPORTANT, safe interpreter, spinbox as entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 slave2
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 1
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {----}

test safePrimarySelection-3.6 {IMPORTANT, safe slave interpreter, spinbox spun, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-3.6 {IMPORTANT, safe interpreter, spinbox spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 slave2
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 2
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {----}

test safePrimarySelection-3.7 {IMPORTANT, safe slave interpreter, spinbox spun/selected/spun, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-3.7 {IMPORTANT, safe interpreter, spinbox spun/selected/spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 slave2
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 3
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {----}

test safePrimarySelection-3.8 {IMPORTANT, safe slave interpreter, ttk::spinbox as entry, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-3.8 {IMPORTANT, safe interpreter, ttk::spinbox as entry, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 slave2
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 1
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {----}

test safePrimarySelection-3.9 {IMPORTANT, safe slave interpreter, ttk::spinbox spun, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-3.9 {IMPORTANT, safe interpreter, ttk::spinbox spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 slave2
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 2
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {----}

test safePrimarySelection-3.10 {IMPORTANT, safe slave interpreter, ttk::spinbox spun/selected/spun, no existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-3.10 {IMPORTANT, safe interpreter, ttk::spinbox spun/selected/spun, no existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 slave2
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 3
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {----}

test safePrimarySelection-4.1 {master interpreter, text, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-4.1 {parent interpreter, text, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    ::_test_tmp::tryText
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-4.2 {master interpreter, entry, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-4.2 {parent interpreter, entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    ::_test_tmp::tryEntry
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-4.3 {master interpreter, ttk::entry, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-4.3 {parent interpreter, ttk::entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    ::_test_tmp::tryTtkEntry
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-4.4 {master interpreter, listbox, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-4.4 {parent interpreter, listbox, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    ::_test_tmp::tryListbox
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-4.5 {master interpreter, spinbox as entry, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-4.5 {parent interpreter, spinbox as entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    ::_test_tmp::trySpinbox 1
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-4.6 {master interpreter, spinbox spun, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-4.6 {parent interpreter, spinbox spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    ::_test_tmp::trySpinbox 2
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result 2

test safePrimarySelection-4.7 {master interpreter, spinbox spun/selected/spun, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-4.7 {parent interpreter, spinbox spun/selected/spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    ::_test_tmp::trySpinbox 3
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result 3

test safePrimarySelection-4.8 {master interpreter, ttk::spinbox as entry, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-4.8 {parent interpreter, ttk::spinbox as entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    ::_test_tmp::tryTtkSpinbox 1
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-4.9 {master interpreter, ttk::spinbox spun, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-4.9 {parent interpreter, ttk::spinbox spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    ::_test_tmp::tryTtkSpinbox 2
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result 2

test safePrimarySelection-4.10 {master interpreter, ttk::spinbox spun/selected/spun, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-4.10 {parent interpreter, ttk::spinbox spun/selected/spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    ::_test_tmp::tryTtkSpinbox 3
    ::_test_tmp::getPrimarySelection
} -cleanup {
    destroy {*}[winfo children .]
    ::_test_tmp::clearPrimarySelection
} -result 3

test safePrimarySelection-5.1 {unsafe slave interpreter, text, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-5.1 {child interpreter, text, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set int2 slave2
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryText
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-5.2 {unsafe slave interpreter, entry, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-5.2 {child interpreter, entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set int2 slave2
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryEntry
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-5.3 {unsafe slave interpreter, ttk::entry, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-5.3 {child interpreter, ttk::entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set int2 slave2
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkEntry
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-5.4 {unsafe slave interpreter, listbox, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-5.4 {child interpreter, listbox, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set int2 slave2
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryListbox
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-5.5 {unsafe slave interpreter, spinbox as entry, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-5.5 {child interpreter, spinbox as entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set int2 slave2
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 1
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-5.6 {unsafe slave interpreter, spinbox spun, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-5.6 {child interpreter, spinbox spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set int2 slave2
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 2
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result 2

test safePrimarySelection-5.7 {unsafe slave interpreter, spinbox spun/selected/spun, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-5.7 {child interpreter, spinbox spun/selected/spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set int2 slave2
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 3
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result 3

test safePrimarySelection-5.8 {unsafe slave interpreter, ttk::spinbox as entry, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-5.8 {child interpreter, ttk::spinbox as entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set int2 slave2
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 1
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result {PAYLOAD}

test safePrimarySelection-5.9 {unsafe slave interpreter, ttk::spinbox spun, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-5.9 {child interpreter, ttk::spinbox spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set int2 slave2
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 2
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result 2

test safePrimarySelection-5.10 {unsafe slave interpreter, ttk::spinbox spun/selected/spun, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-5.10 {child interpreter, ttk::spinbox spun/selected/spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set int2 slave2
    set int2 child2
    ::_test_tmp::unsafeInterp $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 3
    $int2 eval ::_test_tmp::getPrimarySelection
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2
    ::_test_tmp::clearPrimarySelection
} -result 3

test safePrimarySelection-6.1 {IMPORTANT, safe slave interpreter, text, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-6.1 {IMPORTANT, safe interpreter, text, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 slave2
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryText
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {OLD_VALUE----OLD_VALUE}

test safePrimarySelection-6.2 {IMPORTANT, safe slave interpreter, entry, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-6.2 {IMPORTANT, safe interpreter, entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 slave2
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryEntry
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {OLD_VALUE----OLD_VALUE}

test safePrimarySelection-6.3 {IMPORTANT, safe slave interpreter, ttk::entry, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-6.3 {IMPORTANT, safe interpreter, ttk::entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 slave2
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkEntry
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {OLD_VALUE----OLD_VALUE}

test safePrimarySelection-6.4 {IMPORTANT, safe slave interpreter, listbox, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-6.4 {IMPORTANT, safe interpreter, listbox, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 slave2
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryListbox
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {OLD_VALUE----OLD_VALUE}

test safePrimarySelection-6.5 {IMPORTANT, safe slave interpreter, spinbox as entry, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-6.5 {IMPORTANT, safe interpreter, spinbox as entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 slave2
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 1
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {OLD_VALUE----OLD_VALUE}

test safePrimarySelection-6.6 {IMPORTANT, safe slave interpreter, spinbox spun, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-6.6 {IMPORTANT, safe interpreter, spinbox spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 slave2
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 2
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {OLD_VALUE----OLD_VALUE}

test safePrimarySelection-6.7 {IMPORTANT, safe slave interpreter, spinbox spun/selected/spun, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-6.7 {IMPORTANT, safe interpreter, spinbox spun/selected/spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 slave2
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::trySpinbox 3
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {OLD_VALUE----OLD_VALUE}

test safePrimarySelection-6.8 {IMPORTANT, safe slave interpreter, ttk::spinbox as entry, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-6.8 {IMPORTANT, safe interpreter, ttk::spinbox as entry, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 slave2
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 1
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {OLD_VALUE----OLD_VALUE}

test safePrimarySelection-6.9 {IMPORTANT, safe slave interpreter, ttk::spinbox spun, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-6.9 {IMPORTANT, safe interpreter, ttk::spinbox spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 slave2
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 2
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2
} -cleanup {
    interp delete $int2
    destroy {*}[winfo children .]
    unset int2 res0 res1 res2 res3
    ::_test_tmp::clearPrimarySelection
} -result {OLD_VALUE----OLD_VALUE}

test safePrimarySelection-6.10 {IMPORTANT, safe slave interpreter, ttk::spinbox spun/selected/spun, existing selection} -setup {
    catch {interp delete slave2}
test safePrimarySelection-6.10 {IMPORTANT, safe interpreter, ttk::spinbox spun/selected/spun, existing selection} -setup {
    catch {interp delete child2}
    destroy {*}[winfo children .]
    ::_test_tmp::setPrimarySelection
} -body {
    set res0 [::_test_tmp::getPrimarySelection]
    set int2 slave2
    set int2 child2
    ::safe::interpCreate $int2
    ::safe::loadTk $int2
    $int2 eval $::_test_tmp::script
    $int2 eval ::_test_tmp::tryTtkSpinbox 3
    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
    set res2 [::_test_tmp::getPrimarySelection]
    set res3 $res0--$res1--$res2

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 (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

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







-
+





-
+






-
+





-
+







} -result 24

test scale-14.5 {RoundValueToResolution procedure} -body {
    .s configure -from -100 -to 0 -sliderlength 10 -length 114 -bd 2 \
        -orient horizontal -resolution 4.0
    update
    .s get 84 152
} -result {-28}
} -result -28
test scale-14.6 {RoundValueToResolution procedure} -body {
    .s configure -from -100 -to 0 -sliderlength 10 -length 114 -bd 2 \
        -orient horizontal -resolution 4.0
    update
    .s get 86 152
} -result {-24}
} -result -24

test scale-14.7 {RoundValueToResolution procedure} -body {
    .s configure -from 0 -to -100 -sliderlength 10 -length 114 -bd 2 \
        -orient horizontal -resolution 4.0
    update
    .s get 84 152
} -result {-72}
} -result -72
test scale-14.8 {RoundValueToResolution procedure} -body {
    .s configure -from 0 -to -100 -sliderlength 10 -length 114 -bd 2 \
        -orient horizontal -resolution 4.0
    update
    .s get 86 152
} -result {-76}
} -result -76

test scale-14.9 {RoundValueToResolution procedure} -body {
    .s configure -from 0 -to 2.25  -sliderlength 10 -length 114 -bd 2 \
        -orient horizontal -resolution 0
    update
    .s get 84 152
} -result {1.64}
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
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







-
+








-
+




















-
+







test scale-15.1 {ScaleVarProc procedure} -setup {
    deleteWindows
} -body {
    set y -130
    scale .s -from 0 -to -200 -variable y -orient horizontal -length 150
    pack .s
    return $y
} -result {-130}
} -result -130
test scale-15.2 {ScaleVarProc procedure} -setup {
    deleteWindows
} -body {
    set y -130
    scale .s -from -200 -to 0 -variable y -orient horizontal -length 150
    pack .s
    set y -87
    .s get
} -result {-87}
} -result -87
test scale-15.3 {ScaleVarProc procedure} -setup {
    deleteWindows
} -body {
    set y -130
    scale .s -from -200 -to 0 -variable y -orient horizontal -length 150
    pack .s
    set y 40q
} -cleanup {
    deleteWindows
} -returnCodes error -result {can't set "y": can't assign non-numeric value to scale variable}
test scale-15.4 {ScaleVarProc procedure} -setup {
    deleteWindows
} -body {
    set y -130
    scale .s -from -200 -to 0 -variable y -orient horizontal -length 150
    pack .s
    catch {set y 40q}
    .s get
} -cleanup {
    deleteWindows
} -result {-130}
} -result -130
test scale-15.5 {ScaleVarProc procedure} -setup {
    deleteWindows
} -body {
    set y 1
    scale .s -from 1 -to 0 -variable y -orient horizontal -length 150
    pack .s
    set y x

Changes to tests/scrollbar.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




-
-
-
+
+
+


-
+


+
+
+
+







# This file is a Tcl script to test out scrollbar widgets and
# the "scrollbar" command of Tk.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.1
package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint 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} {
193
194
195
196
197
198
199
200

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

204
205
206
207
208
209
210
211







-
+







} {}
test scrollbar-3.14.1 {ScrollbarWidgetCmd procedure, "cget" option} emptyTest {
    # empty test; duplicated scrollbar-3.13
} {}
destroy .s2
test scrollbar-3.15 {ScrollbarWidgetCmd procedure, "configure" option} {
    llength [.s configure]
} {20}
} 20
test scrollbar-3.16 {ScrollbarWidgetCmd procedure, "configure" option} {
    list [catch {.s configure -bad} msg] $msg
} {1 {unknown option "-bad"}}
test scrollbar-3.17 {ScrollbarWidgetCmd procedure, "configure" option} {
    .s configure -orient
} {-orient orient Orient vertical vertical}
test scrollbar-3.18 {ScrollbarWidgetCmd procedure, "configure" option} {
226
227
228
229
230
231
232
233

234
235
236
237
238
239
240
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244







-
+







    list [catch {.s delta 18 xxyz} msg] $msg
} {1 {expected integer but got "xxyz"}}
test scrollbar-3.24 {ScrollbarWidgetCmd procedure, "delta" option} {
    list [catch {.s delta 18 xxyz} msg] $msg
} {1 {expected integer but got "xxyz"}}
test scrollbar-3.25 {ScrollbarWidgetCmd procedure, "delta" option} {
    format {%.6g} [.s delta 20 0]
} {0}
} 0
test scrollbar-3.26 {ScrollbarWidgetCmd procedure, "delta" option} {
    format {%.6g} [.s delta 0 20]
} [format %.6g [expr {20.0/([getTroughSize .s]-1)}]]
test scrollbar-3.27 {ScrollbarWidgetCmd procedure, "delta" option} {
    format {%.6g} [.s delta 0 -20]
} [format %.6g [expr {-20.0/([getTroughSize .s]-1)}]]
test scrollbar-3.28 {ScrollbarWidgetCmd procedure, "delta" option} {
258
259
260
261
262
263
264
265

266
267
268

269
270
271
272
273

274
275

276
277
278
279


280
281
282
283
284
285
286
262
263
264
265
266
267
268

269
270
271

272
273
274
275
276

277
278

279
280
281


282
283
284
285
286
287
288
289
290







-
+


-
+




-
+

-
+


-
-
+
+







    list [catch {.s fraction silly 24} msg] $msg
} {1 {expected integer but got "silly"}}
test scrollbar-3.32 {ScrollbarWidgetCmd procedure, "fraction" option} {
    list [catch {.s fraction 24 bogus} msg] $msg
} {1 {expected integer but got "bogus"}}
test scrollbar-3.33 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.s fraction 0 0]
} {0}
} 0
test scrollbar-3.34 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.s fraction 0 1000]
} {1}
} 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 {
test scrollbar-3.36 {ScrollbarWidgetCmd procedure, "fraction" option} {x11 failsOnUbuntu failsOnXQuarz} {
    format {%.6g} [.s fraction 4 179]
} {1}
} 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 {
} 1
test scrollbar-3.38 {ScrollbarWidgetCmd procedure, "fraction" option} {x11 failsOnUbuntu failsOnXQuarz} {
    format {%.6g} [.s fraction 4 178]
} {0.993711}
test scrollbar-3.39 {ScrollbarWidgetCmd procedure, "fraction" option} {testmetrics win} {
    expr {
    [format {%.6g} [.s fraction 4 [expr {200 - [testmetrics cyvscroll .s] - 2}]]]
	== [format %g [expr {(200.0 - [testmetrics cyvscroll .s]*2 - 2)
			   / ($height - 1 - [testmetrics cyvscroll .s]*2)}]]}
305
306
307
308
309
310
311
312

313
314
315
316
317

318
319
320
321
322
323
324
309
310
311
312
313
314
315

316
317
318
319
320

321
322
323
324
325
326
327
328







-
+




-
+







        # macOS aqua
        place configure .t.s -width [expr {2*([.t.s cget -highlightthickness] + [.t.s cget -bd])}]
    }
}
update
test scrollbar-3.42 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.t.s fraction 100 0]
} {0}
} 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} {
test scrollbar-3.44 {ScrollbarWidgetCmd procedure, "get" option} nodeprecated {
    .s set 100 10 13 14
    .s get
} {100 10 13 14}
test scrollbar-3.45 {ScrollbarWidgetCmd procedure, "get" option} {
    .s set 0.6 0.8
    set result {}
    foreach element [.s get] {
337
338
339
340
341
342
343
344

345
346
347
348
349
350
351
341
342
343
344
345
346
347

348
349
350
351
352
353
354
355







-
+







} {1 {expected integer but got "bogus"}}
test scrollbar-3.49 {ScrollbarWidgetCmd procedure, "identify" option} {
    list [catch {.s identify -1 bogus} msg] $msg
} {1 {expected integer but got "bogus"}}
test scrollbar-3.50.1 {ScrollbarWidgetCmd procedure, "identify" option} notAqua {
    .s identify 5 5
} {arrow1}
test scrollbar-3.50.1 {ScrollbarWidgetCmd procedure, "identify" option} aqua {
test scrollbar-3.50.2 {ScrollbarWidgetCmd procedure, "identify" option} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 5 5
} {trough1}
test scrollbar-3.51 {ScrollbarWidgetCmd procedure, "identify" option} {
    .s identify 5 35
} {trough1}
test scrollbar-3.52 {ScrollbarWidgetCmd procedure, "identify" option} {
395
396
397
398
399
400
401
402

403
404
405

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
430
431
432
433







-
+


-
+


-
+


-
+


-
+



-
+



-
+







    .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} {
test scrollbar-3.64 {ScrollbarWidgetCmd procedure, "set" option} nodeprecated {
    list [catch {.s set abc def ghi jkl} msg] $msg
} {1 {expected integer but got "abc"}}
test scrollbar-3.65 {ScrollbarWidgetCmd procedure, "set" option} {
test scrollbar-3.65 {ScrollbarWidgetCmd procedure, "set" option} nodeprecated {
    list [catch {.s set 1 def ghi jkl} msg] $msg
} {1 {expected integer but got "def"}}
test scrollbar-3.66 {ScrollbarWidgetCmd procedure, "set" option} {
test scrollbar-3.66 {ScrollbarWidgetCmd procedure, "set" option} nodeprecated {
    list [catch {.s set 1 2 ghi jkl} msg] $msg
} {1 {expected integer but got "ghi"}}
test scrollbar-3.67 {ScrollbarWidgetCmd procedure, "set" option} {
test scrollbar-3.67 {ScrollbarWidgetCmd procedure, "set" option} nodeprecated {
    list [catch {.s set 1 2 3 jkl} msg] $msg
} {1 {expected integer but got "jkl"}}
test scrollbar-3.68 {ScrollbarWidgetCmd procedure, "set" option} {
test scrollbar-3.68 {ScrollbarWidgetCmd procedure, "set" option} nodeprecated {
    .s set -10 50 20 30
    .s get
} {0 50 0 0}
test scrollbar-3.69 {ScrollbarWidgetCmd procedure, "set" option} {
test scrollbar-3.69 {ScrollbarWidgetCmd procedure, "set" option} nodeprecated {
    .s set 100 -10 20 30
    .s get
} {100 0 20 30}
test scrollbar-3.70 {ScrollbarWidgetCmd procedure, "set" option} {
test scrollbar-3.70 {ScrollbarWidgetCmd procedure, "set" option} nodeprecated {
    .s set 100 50 30 20
    .s get
} {100 50 30 30}
test scrollbar-3.71 {ScrollbarWidgetCmd procedure, "set" option} {
    list [catch {.s set 1 2 3} msg] $msg
} {1 {wrong # args: should be ".s set firstFraction lastFraction"}}
test scrollbar-3.72 {ScrollbarWidgetCmd procedure, "set" option} {
487
488
489
490
491
492
493
494

495
496
497
498
499
500
501
491
492
493
494
495
496
497

498
499
500
501
502
503
504
505







-
+







test scrollbar-6.11.1 {ScrollbarPosition procedure} x11 {
    .s identify 8 4
} {arrow1}
test scrollbar-6.11.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 8 4
} {trough1}
test scrollbar-6.12.1 {ScrollbarPosition procedure} x11 {
test scrollbar-6.12.1 {ScrollbarPosition procedure} {x11 failsOnUbuntu failsOnXQuarz} {
    .s identify 8 19
} {arrow1}
test scrollbar-6.12.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 8 19
} {trough1}
test scrollbar-6.14 {ScrollbarPosition procedure} win {
545
546
547
548
549
550
551
552

553
554
555
556
557
558
559
549
550
551
552
553
554
555

556
557
558
559
560
561
562
563







-
+







    .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 {
test scrollbar-6.29.1 {ScrollbarPosition procedure} {x11 failsOnUbuntu failsOnXQuarz} {
    .s identify 8 180
} {arrow2}
test scrollbar-6.29.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 8 180
} {trough2}
test scrollbar-6.30.1 {ScrollbarPosition procedure} x11 {
569
570
571
572
573
574
575
576

577
578
579
580
581
582
583
573
574
575
576
577
578
579

580
581
582
583
584
585
586
587







-
+







} {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 {
test scrollbar-6.35 {ScrollbarPosition procedure} {unix failsOnUbuntu failsOnXQuarz} {
    .s identify 18 100
} {trough2}
test scrollbar-6.37 {ScrollbarPosition procedure} win {
    .s identify 0 100
} {trough2}
test scrollbar-6.38 {ScrollbarPosition procedure} win {
    .s identify [expr {[winfo width .s] - 1}] 100
608
609
610
611
612
613
614
615

616
617
618
619
620
621
622
612
613
614
615
616
617
618

619
620
621
622
623
624
625
626







-
+







    # macOS scrollbars have no arrows nowadays
    .t.s identify 82 8
} {trough2}
test scrollbar-6.43 {ScrollbarPosition procedure} {testmetrics win} {
    .t.s identify [expr {int(.4 / [.t.s delta 1 0]) + [testmetrics cxhscroll .t.s]
		       - 1}] [expr {[winfo height .t.s] / 2}]
} {slider}
test scrollbar-6.44 {ScrollbarPosition procedure} unix {
test scrollbar-6.44 {ScrollbarPosition procedure} {unix failsOnUbuntu failsOnXQuarz} {
    .t.s identify 100 18
} {trough2}
test scrollbar-6.46 {ScrollbarPosition procedure} win {
    .t.s identify 100 [expr {[winfo height .t.s] - 1}]
} {trough2}

test scrollbar-7.1 {EventuallyRedraw} {
681
682
683
684
685
686
687
688

689
690
691
692
693
694
695
696
697
698
699
700
701

702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717

718
719
720
721
722
723
724
725
726
727
728
729
730

731
732
733
734
735
736
737
738
739
740
741
742
743
744
745

746
747
748
749
750
751
752
753
754
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
685
686
687
688
689
690
691

692
693
694
695
696
697
698
699
700
701
702
703
704

705














706

707
708
709
710
711
712
713
714
715
716
717
718
719

720















721
722
723
724
725
726
727
728
729
730
731
732
733

734














735
736
737
738
739
740
741







-
+












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

-
+












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












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







    catch {destroy .s}
    scrollbar .s
    interp hide {} .s
    destroy .s
    list [winfo children .] [interp hidden]
} [list {} $l]

test scrollbar-10.1.1 {<MouseWheel> event on scrollbar} -constraints {notAqua} -setup {
test scrollbar-10.1 {<MouseWheel> event on scrollbar} -setup {
    destroy .t .s
} -body {
    pack [text .t -yscrollcommand {.s set}] -side left
    for {set i 1} {$i < 100} {incr i} {.t insert end "Line $i\n"}
    pack [scrollbar .s -command {.t yview}] -fill y -expand 1 -side left
    update
    focus -force .s
    event generate .s <MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {5.0}
} -result {4.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.1 {<Shift-MouseWheel> event on horizontal scrollbar} -constraints {notAqua} -setup {
test scrollbar-10.2 {<MouseWheel> event on scrollbar} -setup {
    destroy .t .s
} -body {
    pack [text .t -xscrollcommand {.s set} -wrap none] -side top
    for {set i 1} {$i < 100} {incr i} {.t insert end "Char $i "}
    pack [scrollbar .s -command {.t xview} -orient horizontal] -fill x -expand 1 -side top
    update
    focus -force .s
    event generate .s <Shift-MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {1.4}
} -result {1.3}
test scrollbar-10.2.2 {<Shift-MouseWheel> event on horizontal 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 <Shift-MouseWheel> -delta -4
    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} -constraints {notAqua} -setup {
test scrollbar-10.3 {<MouseWheel> event on horizontal scrollbar} -setup {
    destroy .t .s
} -body {
    pack [text .t -xscrollcommand {.s set} -wrap none] -side top
    for {set i 1} {$i < 100} {incr i} {.t insert end "Char $i "}
    pack [scrollbar .s -command {.t xview} -orient horizontal] -fill x -expand 1 -side top
    update
    focus -force .s
    event generate .s <MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {1.4}
} -result {1.3}
test scrollbar-10.2.4 {<MouseWheel> event on horizontal 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 -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
        }
    }

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
1
2
3
4


5
6
7
8
9
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 (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 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(CI)] || ![string match Linux $::tcl_platform(os)]}]

global longValue selValue selInfo

set selValue {}
set selInfo {}

proc handler {type offset count} {
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
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







-
+












-
+












-
+







    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} -result {{0x400 } {TEST 0 4000}}
test select-9.2 {SelCvtToX and SelCvtFromX procedures} -setup {
    setup
    setupbg
} -constraints x11 -body {
} -constraints {x11 failsOnUbuntu} -body {
    set selValue "1024 0xffff  2048 -2  "
    set selInfo ""
    selection handle -selection PRIMARY -format INTEGER -type TEST \
	.f1 {handler TEST}
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} -result {{0x400 0xffff 0x800 0xfffffffe } {TEST 0 4000}}
test select-9.3 {SelCvtToX and SelCvtFromX procedures} -setup {
    setup
    setupbg
} -constraints x11 -body {
} -constraints {x11 failsOnUbuntu} -body {
    set selValue "   "
    set selInfo ""
    selection handle -selection PRIMARY -format INTEGER -type TEST \
	.f1 {handler TEST}
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} -result {{ } {TEST 0 4000}}
test select-9.4 {SelCvtToX and SelCvtFromX procedures} -setup {
    setup
    setupbg
} -constraints x11 -body {
} -constraints {x11 failsOnUbuntu} -body {
    set selValue "16 foobar 32"
    set selInfo ""
    selection handle -selection PRIMARY -format INTEGER -type TEST \
	.f1 {handler TEST}
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
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
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







-
+














-
+














-
+







    dobg {selection get ERROR}
} -cleanup {
    cleanupbg
} -result {PRIMARY selection doesn't exist or form "ERROR" not defined}
# testing timers
# This one hangs in Exceed
test select-10.4 {ConvertSelection procedure} -constraints {
    x11 noExceed
    x11 noExceed failsOnUbuntu
} -setup {
    setup
    setupbg
} -body {
    set selValue $longValue
    set selInfo ""
    selection handle .f1 {errIncrHandler STRING}
    set result ""
    set pass 0
    lappend result [dobg {selection get}]
    cleanupbg
    lappend result $selInfo
} -result {{selection owner didn't respond} {STRING 0 4000 STRING 4000 4000 STRING 8000 4000 STRING 12000 4000 STRING 16000 4000 STRING 0 4000 STRING 4000 4000}}
test select-10.5 {ConvertSelection procedure, reentrancy issues} -constraints {
    x11
    x11 failsOnUbuntu
} -setup {
    setup
    setupbg
} -body {
    set selValue "Test value"
    set selInfo ""
    selection handle -type TEST .f1 { handler TEST }
    selection handle -type STRING .f1 { badHandler .f1 STRING }
    set result ""
    lappend result [dobg {selection get}]
    cleanupbg
    lappend result $selInfo
} -result {{PRIMARY selection doesn't exist or form "STRING" not defined} {.f1 STRING 0 4000}}
test select-10.6 {ConvertSelection procedure, reentrancy issues} -constraints {
    x11
    x11 failsOnUbuntu
} -setup {
    setup
    setupbg
} -body {
    proc weirdHandler {type offset count} {
	destroy .f1
	handler $type $offset $count
1055
1056
1057
1058
1059
1060
1061
1062

1063
1064
1065
1066
1067
1068
1069
1056
1057
1058
1059
1060
1061
1062

1063
1064
1065
1066
1067
1068
1069
1070







-
+







} -cleanup {
    rename weirdHandler {}
} -result {{PRIMARY selection doesn't exist or form "STRING" not defined} {STRING 0 4000}}

##############################################################################

# testing reentrancy
test select-11.1 {TkSelPropProc procedure} -constraints x11 -setup {
test select-11.1 {TkSelPropProc procedure} -constraints {x11 failsOnUbuntu} -setup {
    setup
    setupbg
} -body {
    set selValue $longValue
    set selInfo ""
    selection handle -type TEST .f1 { handler TEST }
    selection handle -type STRING .f1 { reallyBadHandler .f1 STRING }
1127
1128
1129
1130
1131
1132
1133
1134

1135
1136
1137
1138
1139
1140
1141
1128
1129
1130
1131
1132
1133
1134

1135
1136
1137
1138
1139
1140
1141
1142







-
+







    set selInfo ""
    set result [list [selection get TARGETS] $selInfo]
    selection handle .f1 {} TARGETS
    lappend result [selection get TARGETS]
} -result {{Targets value} {TARGETS.f1 0 4000} {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}}

test select-13.1 {SelectionSize procedure, handler deleted} -constraints {
    x11
    x11 failsOnUbuntu
} -setup {
    setup
    setupbg
} -body {
    proc badHandler {path type offset count} {
	global selValue selInfo abortCount
	incr abortCount -1

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
1
2
3
4




5
6
7
8
9
10
11
12

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




-
-
-
-
+
+
+
+




-
+




+







# This file is a Tcl script to test out the "send" command and the
# other procedures in the file tkSend.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright (c) 2001 by ActiveState Corporation.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# Copyright © 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.1
package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint xhost [llength [auto_execok xhost]]
testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]

# 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
282
283
284
285
286
287
288
289

290
291
292
293
294
295
296
297
298
299

300
301
302
303
304
305
306
283
284
285
286
287
288
289

290
291
292
293
294
295
296
297
298
299

300
301
302
303
304
305
306
307







-
+









-
+







test send-8.14 {Tk_SendCmd procedure, local interp killed by send} {secureserver testsend} {
    newApp "" t_s_2 Test
    list [catch {send t_s_2 {destroy .; concat result}} msg] $msg
} {0 result}

catch {interp delete t_s_2}

test send-8.15 {Tk_SendCmd procedure, local interp, error info} {secureserver testsend} {
test send-8.15 {Tk_SendCmd procedure, local interp, error info} {secureserver testsend failsOnUbuntu} {
    catch {error foo}
    list [catch {send t_s_1 {if 1 {open bogus_file_name}}} msg] $msg $errorInfo $errorCode
} {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} {
test send-8.16 {Tk_SendCmd procedure, bogusCommWindow} {secureserver testsend failsOnUbuntu} {
    testsend prop root InterpRegistry "10234 bogus\n"
    set result [list [catch {send bogus bogus command} msg] $msg]
    winfo interps
    tk appname tktest
    set result
} {1 {no application named "bogus"}}

397
398
399
400
401
402
403
404

405
406
407
408
409
410
411

412
413
414
415
416
417
418
398
399
400
401
402
403
404

405
406
407
408
409
410
411

412
413
414
415
416
417
418
419







-
+






-
+







} {12345 newA newB}
test send-10.4 {SendEventProc procedure, leading nulls, bogus commands} {secureserver testsend} {
    testsend prop comm Comm \
	    "\n\nx\n-bogus\n\nc\n-n tktest\n-s set a 44\n"
    set a null
    update
    set a
} {44}
} 44
test send-10.5 {SendEventProc procedure, extraneous command options} {secureserver testsend} {
    testsend prop comm Comm \
	    "c\n-n tktest\n-x miscellanous\n-y who knows?\n-s set a new\n"
    set a null
    update
    set a
} {new}
} new
test send-10.6 {SendEventProc procedure, unknown interpreter} {secureserver testsend} {
    testsend prop [winfo id .f] Comm {}
    testsend prop comm Comm \
	    "c\n-n unknown\n-r $id 44\n-s set a new\n"
    set a null
    update
    list [testsend prop [winfo id .f] Comm] $a
518
519
520
521
522
523
524
525

526
527
528


529
530
531
532
533
534
535
519
520
521
522
523
524
525

526
527


528
529
530
531
532
533
534
535
536







-
+

-
-
+
+







    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
1
2
3



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



-
-
-
+
+
+







+
+
+

+







# This file is a Tcl script to test spinbox widgets in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 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(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint failsOnUbuntuNoXft [expr {[testConstraint failsOnUbuntu] || (![catch {tk::pkgconfig get fontsystem} fs] && ($fs eq "xft"))}]

# For xscrollcommand
set scrollInfo {}
proc scroll args {
        global scrollInfo
        set scrollInfo $args
}
# For trace variable
proc override args {
        global x
709
710
711
712
713
714
715
716

717
718
719
720
721
722
723
713
714
715
716
717
718
719

720
721
722
723
724
725
726
727







-
+







    pack .e
    update
} -body {
    .e configure -repeatinterval -500
    .e cget -repeatinterval
} -cleanup {
    destroy .e
} -result {-500}
} -result -500
test spinbox-1.62 {configuration option: "repeatinterval" for spinbox} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -repeatinterval 3p
911
912
913
914
915
916
917
918

919
920
921
922
923
924
925


926
927
928
929
930
931
932
915
916
917
918
919
920
921

922
923
924
925
926
927


928
929
930
931
932
933
934
935
936







-
+





-
-
+
+







    update
} -body {
    .e configure -values {bad {}list}
} -cleanup {
    destroy .e
} -returnCodes {error} -result {list element in braces followed by "list" instead of space}

test spinbox-1.80 {configuration option: "vcmd"} -setup {
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
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
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







-
+












-
+







	fonts
} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
# Tcl_UtfAtIndex(): utf at end
    .e insert 0 "ab\u4e4e"
    .e insert 0 "ab"
    .e bbox end
} -cleanup {
    destroy .e
} -result {19 5 12 13}
test spinbox-3.8 {SpinboxWidgetCmd procedure, "bbox" widget command} -constraints {
	fonts
} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
# Tcl_UtfAtIndex(): utf before index
    .e insert 0 "ab\u4e4ec"
    .e insert 0 "abc"
    .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
1117
1118
1119
1120
1121
1122
1123
1124

1125
1126
1127
1128
1129
1130
1131
1121
1122
1123
1124
1125
1126
1127

1128
1129
1130
1131
1132
1133
1134
1135







-
+







test spinbox-3.10 {SpinboxWidgetCmd procedure, "bbox" widget command} -constraints {
	fonts
} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert 0 "abcdefghij\u4e4eklmnop"
    .e insert 0 "abcdefghijklmnop"
    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 {
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
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







-
+



-
+



-
+




-
+







test spinbox-3.24 {SpinboxWidgetCmd procedure, "delete" widget command} -setup {
    spinbox .e
    pack .e
    update
    set x {}
} -body {
# UTF
    .e insert end "01234\u4e4e67890"
    .e insert end "0123467890"
    .e delete 6
    lappend x [.e get]
    .e delete 0 end
    .e insert end "012345\u4e4e7890"
    .e insert end "0123457890"
    .e delete 6
    lappend x [.e get]
    .e delete 0 end
    .e insert end "0123456\u4e4e890"
    .e insert end "0123456890"
    .e delete 6
    lappend x [.e get]
} -cleanup {
    destroy .e
} -result [list "01234\u4e4e7890" "0123457890" "012345\u4e4e890"]
} -result [list "012347890" "0123457890" "012345890"]
test spinbox-3.25 {SpinboxWidgetCmd procedure, "delete" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e delete 6 5
1348
1349
1350
1351
1352
1353
1354
1355

1356
1357
1358
1359
1360
1361
1362
1352
1353
1354
1355
1356
1357
1358

1359
1360
1361
1362
1363
1364
1365
1366







-
+







} -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\u4e4e\u0153def
    .e insert 0 abc乎œdef
    list [.e index 3] [.e index 4] [.e index end]
} -cleanup {
    destroy .e
} -result {3 4 8}
test spinbox-3.36 {SpinboxWidgetCmd procedure, "insert" widget command} -setup {
    spinbox .e
} -body {
1780
1781
1782
1783
1784
1785
1786
1787

1788
1789
1790
1791
1792
1793
1794
1784
1785
1786
1787
1788
1789
1790

1791
1792
1793
1794
1795
1796
1797
1798







-
+







} -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 integer but got "gorp"}
} -returnCodes error -result {expected floating-point number but got "gorp"}
test spinbox-3.73 {SpinboxWidgetCmd procedure, "xview" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
1867
1868
1869
1870
1871
1872
1873
1874

1875
1876
1877
1878
1879
1880
1881
1871
1872
1873
1874
1875
1876
1877

1878
1879
1880
1881
1882
1883
1884
1885







-
+







    pack .e
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview 0
    update
    .e xview -4
    .e xview -1
    .e index @0
} -cleanup {
    destroy .e
} -result 0
test spinbox-3.80 {SpinboxWidgetCmd procedure, "xview" widget command} -setup {
    spinbox .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
1890
1891
1892
1893
1894
1895
1896
1897

1898
1899
1900
1901
1902
1903
1904
1894
1895
1896
1897
1898
1899
1900

1901
1902
1903
1904
1905
1906
1907
1908







-
+







} -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 \u4e4e
    .e insert 10 
    update
# UTF
# If Tcl_NumUtfChars wasn't used, wrong answer would be:
# 0.106383 0.117021 0.117021
    set x {}
    .e xview moveto .1
    lappend x [format {%.6f} [lindex [.e xview] 0]]
2009
2010
2011
2012
2013
2014
2015

2016

2017
2018

2019
2020
2021
2022
2023
2024
2025
2013
2014
2015
2016
2017
2018
2019
2020

2021

2022
2023
2024
2025
2026
2027
2028
2029
2030







+
-
+
-

+








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 "timeout"}]
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    vwait scrollInfo
    .e configure -width 5
    vwait scrollInfo
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.000000 0.363636}

test spinbox-5.8 {ConfigureSpinbox procedure} -constraints {
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
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







+
+

-















+
+

-







    unset -nocomplain contents
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    .e insert 0 abcde
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 2 XXX
    set timeout [after 500 {set $scrollInfo "timeout"}]
    vwait scrollInfo
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abXXXcde abXXXcde {0.000000 1.000000}}

test spinbox-7.2 {InsertChars procedure} -setup {
    unset -nocomplain contents
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    .e insert 0 abcde
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 500 XXX
    set timeout [after 500 {set $scrollInfo "timeout"}]
    vwait scrollInfo
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abcdeXXX abcdeXXX {0.000000 1.000000}}
test spinbox-7.3 {InsertChars procedure} -setup {
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
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







+
+

-














-
-
+
+
+














+
+

-







    unset -nocomplain contents
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    .e insert 0 abcde
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e delete 2 4
    set timeout [after 500 {set $scrollInfo "timeout"}]
    vwait scrollInfo
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abe abe {0.000000 1.000000}}
test spinbox-8.2 {DeleteChars procedure} -setup {
    unset -nocomplain contents
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    .e insert 0 abcde
    .e delete -2 2
    set timeout [after 500 {set $scrollInfo "timeout"}]
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e delete -1 2
    vwait scrollInfo
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {cde cde {0.000000 1.000000}}
test spinbox-8.3 {DeleteChars procedure} -setup {
    unset -nocomplain contents
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    .e insert 0 abcde
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e delete 3 1000
    set timeout [after 500 {set $scrollInfo "timeout"}]
    vwait scrollInfo
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abc abc {0.000000 1.000000}}
test spinbox-8.4 {DeleteChars procedure} -setup {
2607
2608
2609
2610
2611
2612
2613
2614

2615
2616
2617
2618
2619
2620
2621
2617
2618
2619
2620
2621
2622
2623

2624
2625
2626
2627
2628
2629
2630
2631







-
+







    .e xview 4
    .e delete 4 6
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 4
test spinbox-8.18 {DeleteChars procedure} -setup {
test spinbox-8.18 {DeleteChars procedure} -constraints failsOnUbuntuNoXft -setup {
    spinbox .e -width 0 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 "xyzzy"
    update
    .e delete 2 4
3111
3112
3113
3114
3115
3116
3117
3118

3119
3120
3121
3122
3123
3124
3125
3121
3122
3123
3124
3125
3126
3127

3128
3129
3130
3131
3132
3133
3134
3135







-
+







test spinbox-13.23 {GetSpinboxIndex procedure} -body {
    spinbox .e -width 5 -relief sunken -highlightthickness 2 -bd 2 \
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index -10
    .e index -1
} -cleanup {
    destroy .e
} -result 0
test spinbox-13.24 {GetSpinboxIndex procedure} -body {
    spinbox .e -width 5 -relief sunken -highlightthickness 2 -bd 2 \
        -font {Courier -12}
    pack .e
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
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







+
+


-










-
-
+
+
+









+
+

-
+
-





-
+






-
+

+
+







    destroy .e
} -result {0.000000 1.000000}


test spinbox-17.1 {SpinboxUpdateScrollbar procedure} -body {
    spinbox .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e delete 0 end
    .e insert 0 123
    set timeout [after 500 {set $scrollInfo "timeout"}]
    vwait scrollInfo
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.000000 1.000000}
test spinbox-17.2 {SpinboxUpdateScrollbar procedure} -body {
    spinbox .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e
    .e insert 0 0123456789abcdef
    .e xview 3
    set timeout [after 500 {set $scrollInfo "timeout"}]
    update idletasks
    set timeout [after 500 {set $scrollInfo {-1000000 -1000000}}]
    .e xview 3
    vwait scrollInfo
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.187500 0.812500}
test spinbox-17.3 {SpinboxUpdateScrollbar procedure} -body {
    spinbox .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 abcdefghijklmnopqrs
    .e xview 6
    .e xview
    set timeout [after 500 {set $scrollInfo "timeout"}]
    vwait scrollInfo
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.315789 0.842105}
} -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 -xscrollcommand thisisnotacommand
    spinbox .e -width 5
    pack .e
    update idletasks
    .e configure -xscrollcommand thisisnotacommand
    vwait x
    list $x $errorInfo
} -cleanup {
    destroy .e
    rename bgerror {}
} -result {{invalid command name "thisisnotacommand"} {invalid command name "thisisnotacommand"
    while executing
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







-
+







    set ::e nextdata                 ;# previous settings

    .e configure -validatecommand [list doval2 %W %d %i %P %s %S %v %V]
    .e validate
    list [.e cget -validate] [.e get] $::vVals
} -cleanup {
    destroy .e
} -result {none mydata {.e -1 -1 nextdata nextdata {} all forced}}
} -result {none nextdata {.e -1 -1 nextdata nextdata {} all forced}}

## This leaves validate alone because we trigger validation through the
## textvar (a write trace), and the write during validation triggers
## nothing (by definition of avoiding loops on var traces).  This is
## one of those "dangerous" conditions where the user will have a
## different value in the spinbox widget shown as is in the textvar.
test spinbox-19.20 {spinbox widget validation} -setup {
3646
3647
3648
3649
3650
3651
3652




















3653
3654
3655
3656
3657
3658
3659
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







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








    .e configure -validate all
    set ::e testdata
    list [.e cget -validate] [.e get] $::e $::vVals
} -cleanup {
    destroy .e
} -result {all testdata mydata {.e -1 -1 testdata mydata {} all forced}}

## This leaves validate alone because we trigger validation through the
## textvar (a write trace), and the write during validation triggers
## nothing (by definition of avoiding loops on var traces).  This is
## one of those "dangerous" conditions where the user will have a
## different value in the entry widget shown as is in the textvar.
test spinbox-19.21 {spinbox widget validation - bug 40e4bf6198} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    spinbox .e -validate key \
        -validatecommand [list doval2 %W %d %i %P %s %S %v %V] \
        -textvariable ::e
    pack .e
    set ::e origdata
    .e insert 0 A
    list [.e cget -validate] [.e get] $::e $::vVals
} -cleanup {
    destroy .e
} -result {none origdata mydata {.e 1 0 Aorigdata origdata A key key}}

##
## End validation tests
##

test spinbox-20.1 {spinbox config, -format specifier} -body {
    spinbox .e
    .e config -format %2f

Added tests/systray.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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# This file is a Tcl script to test systray and sysnotify features in Tk.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright © 2020 Kevin Walzer/WordTech Communications LLC.
# Copyright © 2020 Francois Vogel.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

test systray-1 {systray icon creation, all options} -setup {
    image create photo _book -data R0lGODlhDwAPAKIAAP//////AP8AAMDAwICAgAAAAAAAAAAAACwAAAAADwAPAAADSQhA2u5ksPeKABKSCaya29d4WKgERFF0l1IMQCAKatvBJ0OTdzzXI1xMB3TBZAvATtB6NSLKleXi3OBoLqrVgc0yv+DVSEUuFxIAOw==
} -body {
    tk systray create -image _book -text "Systray sample" \
            -button1 {puts "button 1 click"} -button3 {puts "button 3 click"}
} -cleanup {
    tk systray destroy
    image delete _book
} -result {}

test systray-2 {systray create, argument checking} -body {
    tk systray create
} -returnCodes {error} -result {missing required option "-image"}

test systray-3 {systray create, argument checking} -body {
    tk systray create -text Hell
} -returnCodes {error} -result {missing required option "-image"}

test systray-4 {systray create, argument checking} -setup {
    image create photo _book -data R0lGODlhDwAPAKIAAP//////AP8AAMDAwICAgAAAAAAAAAAAACwAAAAADwAPAAADSQhA2u5ksPeKABKSCaya29d4WKgERFF0l1IMQCAKatvBJ0OTdzzXI1xMB3TBZAvATtB6NSLKleXi3OBoLqrVgc0yv+DVSEUuFxIAOw==
} -body {
    tk systray create -image _book -gorp invalidOption
} -returnCodes {error} -result {unknown option "-gorp": must be -image, -text, -button1 or -button3}

test systray-5 {systray icon creation, only required option present} -setup {
    image create photo _book -data R0lGODlhDwAPAKIAAP//////AP8AAMDAwICAgAAAAAAAAAAAACwAAAAADwAPAAADSQhA2u5ksPeKABKSCaya29d4WKgERFF0l1IMQCAKatvBJ0OTdzzXI1xMB3TBZAvATtB6NSLKleXi3OBoLqrVgc0yv+DVSEUuFxIAOw==
} -body {
    tk systray create -image _book
} -cleanup {
    tk systray destroy
    image delete _book
} -result {}

test systray-6 {systray icon creation, some options present} -setup {
    image create photo _book -data R0lGODlhDwAPAKIAAP//////AP8AAMDAwICAgAAAAAAAAAAAACwAAAAADwAPAAADSQhA2u5ksPeKABKSCaya29d4WKgERFF0l1IMQCAKatvBJ0OTdzzXI1xMB3TBZAvATtB6NSLKleXi3OBoLqrVgc0yv+DVSEUuFxIAOw==
} -body {
    tk systray create -image _book -button3 {puts b3}
} -cleanup {
    tk systray destroy
    image delete _book
} -result {}

test systray-7 {systray icon, all parameters modification, introspection} -setup {
    image create photo _book -data R0lGODlhDwAPAKIAAP//////AP8AAMDAwICAgAAAAAAAAAAAACwAAAAADwAPAAADSQhA2u5ksPeKABKSCaya29d4WKgERFF0l1IMQCAKatvBJ0OTdzzXI1xMB3TBZAvATtB6NSLKleXi3OBoLqrVgc0yv+DVSEUuFxIAOw==
    image create photo _page -data R0lGODlhCwAPAKIAAP//////AMDAwICAgAAA/wAAAAAAAAAAACwAAAAACwAPAAADMzi6CzAugiAgDGE68aB0RXgRJBFVX0SNpQlUWfahQOvSsgrX7eZJMlQMWBEYj8iQchlKAAA7
} -body {
    tk systray create -image _book -text "Systray icon text"
    tk systray configure -image _page
    tk systray configure -text "Another text for my icon"
    tk systray configure -button1 {set a 1}
    tk systray configure -button3 {set b 2}
    tk systray configure
} -cleanup {
    tk systray destroy
    image delete _book
    image delete _page
} -result {-image _page -text {Another text for my icon} -button1 {set a 1} -button3 {set b 2}}

test systray-8 {systray icon, single parameter modification, introspection} -setup {
    image create photo _book -data R0lGODlhDwAPAKIAAP//////AP8AAMDAwICAgAAAAAAAAAAAACwAAAAADwAPAAADSQhA2u5ksPeKABKSCaya29d4WKgERFF0l1IMQCAKatvBJ0OTdzzXI1xMB3TBZAvATtB6NSLKleXi3OBoLqrVgc0yv+DVSEUuFxIAOw==
} -body {
    tk systray create -image _book -text "Systray icon text" -button1 {puts b1}
    tk systray configure -button1 {set a 1}
    tk systray configure -button1
} -cleanup {
    tk systray destroy
    image delete _book
} -result {set a 1}

test systray-9 {systray icon, several parameters modification at once, introspection} -setup {
    image create photo _book -data R0lGODlhDwAPAKIAAP//////AP8AAMDAwICAgAAAAAAAAAAAACwAAAAADwAPAAADSQhA2u5ksPeKABKSCaya29d4WKgERFF0l1IMQCAKatvBJ0OTdzzXI1xMB3TBZAvATtB6NSLKleXi3OBoLqrVgc0yv+DVSEUuFxIAOw==
} -body {
    tk systray create -image _book -text "Systray icon text" -button1 {puts b1}
    tk systray configure -button1 {set a 1} -text NewText
    list [tk systray configure -button1] [tk systray configure -text]
} -cleanup {
    tk systray destroy
    image delete _book
} -result {{set a 1} NewText}

test systray-10 {configure non-existing systray icon} -setup {
    catch {tk systray destroy}
} -body {
    tk systray configure
} -returnCodes {error} -result {systray not created}

test systray-11 {destroy non-existing systray icon} -setup {
    catch {tk systray destroy}
} -body {
    tk systray destroy
} -returnCodes {error} -result {systray not created}

test systray-12 {destroy systray icon works} -setup {
    image create photo _book -data R0lGODlhDwAPAKIAAP//////AP8AAMDAwICAgAAAAAAAAAAAACwAAAAADwAPAAADSQhA2u5ksPeKABKSCaya29d4WKgERFF0l1IMQCAKatvBJ0OTdzzXI1xMB3TBZAvATtB6NSLKleXi3OBoLqrVgc0yv+DVSEUuFxIAOw==
} -body {
    tk systray create -image _book
    tk systray destroy
    tk systray create -image _book
} -result {}

test systray-13 {systray icon creation, attempt to create more than one in an interp} -setup {
    image create photo _book -data R0lGODlhDwAPAKIAAP//////AP8AAMDAwICAgAAAAAAAAAAAACwAAAAADwAPAAADSQhA2u5ksPeKABKSCaya29d4WKgERFF0l1IMQCAKatvBJ0OTdzzXI1xMB3TBZAvATtB6NSLKleXi3OBoLqrVgc0yv+DVSEUuFxIAOw==
} -body {
    tk systray create -image _book
    tk systray create -image _book
} -cleanup {
    tk systray destroy
    image delete _book
} -returnCodes {error} -result {only one system tray icon supported per interpeter}

test systray-14 {systray icon creation, create one per interp, visibiliy checks} -setup {
    image create photo _book -data R0lGODlhDwAPAKIAAP//////AP8AAMDAwICAgAAAAAAAAAAAACwAAAAADwAPAAADSQhA2u5ksPeKABKSCaya29d4WKgERFF0l1IMQCAKatvBJ0OTdzzXI1xMB3TBZAvATtB6NSLKleXi3OBoLqrVgc0yv+DVSEUuFxIAOw==
} -body {
    tk systray create -image _book -text "first interp"
    interp create second
    # load Tk into the 'second' interp
    foreach pkg [info loaded] {
        if {[lindex $pkg 1] == "Tk"} {
        set loadTk "load $pkg"
        break
        }
    }
    eval $loadTk second
    # create the icon in the 'second' interp
    second eval {
        # should trigger an error: image _book unknown in 'second' interp'
        # image from higer interp should not be visible by 'tk systray'
        tk systray create -image _book -text "second interp"
    }
} -cleanup {
    tk systray destroy
    image delete _book
    interp delete second
} -returnCodes {error} -result {image "_book" doesn't exist}

test systray-15 {systray icon creation, create one per interp} -setup {
    image create photo _book -data R0lGODlhDwAPAKIAAP//////AP8AAMDAwICAgAAAAAAAAAAAACwAAAAADwAPAAADSQhA2u5ksPeKABKSCaya29d4WKgERFF0l1IMQCAKatvBJ0OTdzzXI1xMB3TBZAvATtB6NSLKleXi3OBoLqrVgc0yv+DVSEUuFxIAOw==
} -body {
    tk systray create -image _book -text "first interp"
    interp create second
    # load Tk into the 'second' interp
    foreach pkg [info loaded] {
        if {[lindex $pkg 1] == "Tk"} {
        set loadTk "load $pkg"
        break
        }
    }
    eval $loadTk second
    # create the icon in the 'second' interp
    second eval {
        image create photo _page -data R0lGODlhCwAPAKIAAP//////AMDAwICAgAAA/wAAAAAAAAAAACwAAAAACwAPAAADMzi6CzAugiAgDGE68aB0RXgRJBFVX0SNpQlUWfahQOvSsgrX7eZJMlQMWBEYj8iQchlKAAA7
        tk systray create -image _page -text "second interp"
    }
} -cleanup {
    second eval {
        tk systray destroy
        image delete _page
    }
    interp delete second
    tk systray destroy
    image delete _book
} -result {}

test systray-16 {systray icon creation from a bitmap, on Linux and macOS only} -constraints {
    nonwin
} -setup {
    set data1 {
        #define foo_width 16
        #define foo_height 16
        static unsigned char foo_bits[] = {
           0xff, 0xff, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
           0x81, 0x81, 0xff, 0xff, 0xff, 0xff, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
           0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xff, 0xff
        };
    }
    image create bitmap cross -data $data1
} -body {
    tk systray create -image cross
} -cleanup {
    tk systray destroy
    image delete cross
} -result {}


test sysnotify-1 {system notification popup} -setup {
    image create photo _book -data R0lGODlhDwAPAKIAAP//////AP8AAMDAwICAgAAAAAAAAAAAACwAAAAADwAPAAADSQhA2u5ksPeKABKSCaya29d4WKgERFF0l1IMQCAKatvBJ0OTdzzXI1xMB3TBZAvATtB6NSLKleXi3OBoLqrVgc0yv+DVSEUuFxIAOw==
    tk systray create -image _book -text "Systray sample"
} -body {
    tk sysnotify {Alert} {This is an alert}
} -cleanup {
    tk systray destroy
    image delete _book
} -result {}

test sysnotify-2.1 {system notification stems from a systray icon on Windows} -constraints {
    win
} -setup {
    catch {tk systray destroy}
} -body {
    tk sysnotify {Alert} {This is an alert}
} -returnCodes {error} -result {must create a system tray icon with the "tk systray" command first}
test sysnotify-2.2 {system notification is not linked to any systray icon on X11 or aqua} -constraints {
    nonwin
} -setup {
    catch {tk systray destroy}
} -body {
    tk sysnotify {Alert} {This is an alert}
} -result {}


cleanupTests

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 (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

1248
1249
1250
1251
1252
1253
1254
1255

1256
1257
1258
1259
1260
1261
1262
1248
1249
1250
1251
1252
1253
1254

1255
1256
1257
1258
1259
1260
1261
1262







-
+







12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t configure -state disabled
    .t delete 2.3
    .t g 2.0 2.end
    .t get 2.0 2.end
} -cleanup {
    destroy .t
} -result {abcdefghijklm}
test text-8.6 {TextWidgetCmd procedure, "delete" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
1510
1511
1512
1513
1514
1515
1516
1517

1518
1519

1520
1521
1522
1523
1524
1525
1526
1510
1511
1512
1513
1514
1515
1516

1517
1518

1519
1520
1521
1522
1523
1524
1525
1526







-
+

-
+







Line 7"
    set prevtext [.t get 1.0 end-1c]
    .t configure -undo 0
    .t configure -undo 1
    # Ensure that undo (even composite undo like 'replace')
    # works when the widget shows nothing useful.
    .t replace 2.1 2.3 foo
    .t configure -start 1 -end 1
    .t configure -startline 1 -endline 1
    .t edit undo
    .t configure -start {} -end {}
    .t configure -startline {} -endline {}
    .t configure -undo 0
    string equal [.t get 1.0 end-1c] $prevtext
} -cleanup {
    destroy .t
} -result 1
test text-8.24 {TextWidgetCmd procedure, "replace" option with peers, undo} -setup {
    text .t
1536
1537
1538
1539
1540
1541
1542
1543

1544
1545
1546

1547
1548
1549
1550
1551
1552
1553
1536
1537
1538
1539
1540
1541
1542

1543
1544
1545

1546
1547
1548
1549
1550
1551
1552
1553







-
+


-
+







    .t configure -undo 0
    .t configure -undo 1
    .t peer create .tt -undo 1
# Ensure that undo (even composite undo like 'replace')
# works when the the event took place in one peer, which
# is then deleted, before the undo takes place in another peer.
    .tt replace 2.1 2.3 foo
    .tt configure -start 1 -end 1
    .tt configure -startline 1 -endline 1
    destroy .tt
    .t edit undo
    .t configure -start {} -end {}
    .t configure -startline {} -endline {}
    .t configure -undo 0
    string equal [.t get 1.0 end-1c] $prevtext
} -cleanup {
    destroy .t
} -result 1
test text-8.25 {TextWidgetCmd procedure, "replace" option with peers, undo} -setup {
    text .t
1565
1566
1567
1568
1569
1570
1571
1572

1573
1574

1575
1576
1577
1578
1579

1580
1581
1582
1583
1584
1585
1586
1565
1566
1567
1568
1569
1570
1571

1572
1573

1574
1575
1576
1577
1578

1579
1580
1581
1582
1583
1584
1585
1586







-
+

-
+




-
+







    .t peer create .tt -undo 1
# Ensure that undo (even composite undo like 'replace')
# works when the the event took place in one peer, which
# is then deleted, before the undo takes place in another peer
# which isn't showing everything.
    .tt replace 2.1 2.3 foo
    set res [.tt get 2.1 2.4]
    .tt configure -start 1 -end 1
    .tt configure -startline 1 -endline 1
    destroy .tt
    .t configure -start 3 -end 4
    .t configure -startline 3 -endline 4
# msg will actually be set to a silently ignored error message here,
# (that the .tt command doesn't exist), but that is not important.
    lappend res [catch {.t edit undo}]
    .t configure -undo 0
    .t configure -start {} -end {}
    .t configure -startline {} -endline {}
    lappend res [string equal [.t get 1.0 end-1c] $prevtext]
} -cleanup {
    destroy .t
} -result {foo 0 1}
test text-8.26 {TextWidgetCmd procedure, "replace" option crash} -setup {
    text .tt
} -body {
2064
2065
2066
2067
2068
2069
2070
2071

2072
2073
2074
2075
2076
2077
2078
2064
2065
2066
2067
2068
2069
2070

2071
2072
2073
2074
2075
2076
2077
2078







-
+







} -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"}
2099
2100
2101
2102
2103
2104
2105
2106

2107
2108
2109
2110
2111
2112
2113
2099
2100
2101
2102
2103
2104
2105

2106
2107
2108
2109
2110
2111
2112
2113







-
+







bOy GIrl .#@? x_yz
!@#$%
Line 7"
} -body {
    .t count 5.7 5.3
} -cleanup {
    destroy .t
} -result {-4}
} -result -4
test text-10.7 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
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
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







-
+









-
+







} -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 1.0
} -cleanup {
    destroy .t
} -result {-3}
} -result -3
test text-10.32 {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 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
2644
2645
2646
2647
2648
2649
2650
2651

2652
2653
2654
2655
2656
2657
2658
2644
2645
2646
2647
2648
2649
2650

2651
2652
2653
2654
2655
2656
2657
2658







-
+







} -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 2.7 "1.0 lineend"
} -cleanup {
    destroy .t
} -result {-1}
} -result -1
test text-10.37 {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 configure -wrap none
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
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







-
+















-
+







    lappend res [.t count -displaylines 1.19 3.24] [.t count -displaylines 1.0 end]
    .t tag add hidden 2.9 3.17
    .t tag configure hidden -elide true
    lappend res [.t count -displaylines 1.19 3.24] [.t count -displaylines 1.0 end]
} -cleanup {
    destroy .t
} -result {2 6 1 5}
test text-9.2.45 {TextWidgetCmd procedure, "count" option} -setup {
test text-10.40 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
    pack .t
    update
    set res {}
} -body {
    for {set i 1} {$i < 5} {incr i} {
      .t insert end "Line $i+++Line $i---Line $i///Line $i - This is Line [format %c [expr {64+$i}]]\n"
    }
    .t tag configure hidden -elide true
    .t tag add hidden 2.15 3.10
    .t configure -wrap none
    set res [.t count -displaylines 2.0 3.0]
} -cleanup {
    destroy .t
} -result 0
test text-9.2.46 {TextWidgetCmd procedure, "count" option} -setup {
test text-10.41 {TextWidgetCmd procedure, "count" option} -setup {
    toplevel .mytop
    pack [text .mytop.t -font TkFixedFont -bd 0 -padx 0 -wrap char]
    set spec [font measure TkFixedFont "Line 1+++Line 1---Li"]  ; # 20 chars
    append spec x300+0+0
    wm geometry .mytop $spec
    .mytop.t delete 1.0 end
    update
2725
2726
2727
2728
2729
2730
2731
2732

2733
2734
2735
2736
2737
2738
2739
2725
2726
2727
2728
2729
2730
2731

2732
2733
2734
2735
2736
2737
2738
2739







-
+







    .mytop.t tag configure hidden -elide true
    .mytop.t tag add hidden 2.30 3.10
    lappend res [.mytop.t count -displaylines 2.0 3.0]
    lappend res [.mytop.t count -displaylines 2.0 3.50]
} -cleanup {
    destroy .mytop
} -result {1 3}
test text-9.2.47 {TextWidgetCmd procedure, "count" option} -setup {
test text-10.42 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
    pack .t
    update
    set res {}
} -body {
    for {set i 1} {$i < 25} {incr i} {
        .t insert end "Line $i\n"
3118
3119
3120
3121
3122
3123
3124
3125

3126
3127
3128
3129
3130
3131
3132
3118
3119
3120
3121
3122
3123
3124

3125
3126
3127
3128
3129
3130
3131
3132







-
+







    # 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 TkSendVirtualEvent(),
test text-11a.51 {<<WidgetViewSync>> calls Tk_SendVirtualEvent(),
                  NOT Tk_HandleEvent().
                  Bug [b362182e45704dd7bbd6aed91e48122035ea3d16]} -setup {
    destroy .top.t .top
} -body {
    set res {}
    toplevel .top
    pack [text .top.t]
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







-
+







} -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"} {
    set minY 23
    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
} -body {
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
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







-
-
+
+





-
-
+
+






-
+

-
-
+
+







    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\u30c9\u30cabar"
    .t search \u30c9\u30ca 1.0
    .t insert end "fooドナbar"
    .t search ドナ 1.0
} -cleanup {
    destroy .t
} -result {1.3}
test text-22.70 {TextSearchCmd, unicode} -body {
    text .t
    .t insert end "foo\u30c9\u30cabar"
    list [.t search -count n \u30c9\u30ca 1.0] $n
    .t insert end "fooドナbar"
    list [.t search -count n ドナ 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\u30c9"
    .t insert end "foo"
    .t window create end -window .b1
    .t insert end "\u30cabar"
    list [.t search -count n \u30c9\u30ca 1.0] $n
    .t insert end "bar"
    list [.t search -count n ドナ 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
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083



5084
5085

5086
5087
5088
5089
5090
5091
5092
5074
5075
5076
5077
5078
5079
5080



5081
5082
5083
5084

5085
5086
5087
5088
5089
5090
5091
5092







-
-
-
+
+
+

-
+







} -result {1.31}
test text-22.132 {TextSearchCmd, multiline regexp matching} -body {
    pack [text .t]
    .t insert 1.0 {

void
Tcl_SetObjLength(objPtr, length)
    register Tcl_Obj *objPtr;	/* Pointer to object.  This object must
                                * not currently be shared. */
    register int length;	/* Number of bytes desired for string
    Tcl_Obj *objPtr;		/* Pointer to object.  This object must
				 * not currently be shared. */
    int length;			/* Number of bytes desired for string
				 * representation of object, not including
                            * terminating null byte. */
				 * terminating null byte. */
\{
    char *new;
}
    set markExpr "^(\[A-Za-z0-9~_\]+\[ \t\n\r\]*\\(|(\[^ \t\(#\n\r/@:\*\]\[^=\(\r\n\]*\[ \t\]+\\*?)?"
    append markExpr "(\[A-Za-z0-9~_\]+(<\[^>\]*>)?(::)?(\[A-Za-z0-9~_\]+::)*\[-A-Za-z0-9~_+ <>\|\\*/\]+|\[A-Za-z0-9~_\]+)"
    append markExpr "\[ \n\t\r\]*\\()"
    .t search -all -regexp -- $markExpr 1.0
5820
5821
5822
5823
5824
5825
5826
5827

5828
5829
5830
5831
5832
5833
5834
5820
5821
5822
5823
5824
5825
5826

5827
5828
5829
5830
5831
5832
5833
5834







-
+







} -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 \u00c4 {} xyz e bb
    .t insert end Ä {} 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"]
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
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







-
+



-
+



-
+



-
+







    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 \xb1\xb1\xb1
    .t insert 1.0 ±±±
    .t dump -all 1.0 2.0
} -cleanup {
    destroy .t
} -result "text \xb1\xb1\xb1 1.0 mark insert 1.3 mark current 1.3 text {\n} 1.3"
} -result "text ±±± 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\xb1\xb1\xb1
    .t insert 1.0 abc±±±
    .t dump -all 1.0 2.0
} -cleanup {
    destroy .t
} -result "text abc\xb1\xb1\xb1 1.0 mark insert 1.6 mark current 1.6 text {\n} 1.6"
} -result "text abc±±± 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"
6755
6756
6757
6758
6759
6760
6761
6762

6763
6764
6765
6766
6767
6768
6769
6755
6756
6757
6758
6759
6760
6761

6762
6763
6764
6765
6766
6767
6768
6769







-
+







    event generate .t <<Cut>>
    update
    set ::retval
} -cleanup {
    destroy .t
} -result {no_<<Selection>>_event_fired}
test text-27.16 {-maxundo configuration option} -body {
    text .t -undo 1  -autoseparators 1 -maxundo 2
    text .t -undo 1 -autoseparators 1 -maxundo 2
    pack .t
    .t insert end "line 1\n"
    .t delete 1.4 1.6
    .t insert end "line 2\n"
    catch {.t edit undo}
    catch {.t edit undo}
    catch {.t edit undo}
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
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







-
+

-
+


-
+












-
+





-
+







    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 [lsearch [.t mark names] tk::undoMark*]
    lappend res [expr {[lsearch [.t mark names] tk::undoMark*]<0}]
    .t edit redo
    lappend res [lsearch [.t mark names] tk::undoMark*]
    lappend res [expr {[lsearch [.t mark names] tk::undoMark*]<0}]
} -cleanup {
    destroy .t
} -result [list -1 -1]
} -result {1 1}


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}
    .t configure -tabs 0
} -cleanup {
    destroy .t
} -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}
    .t configure -tabs -5
} -cleanup {
    destroy .t
} -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
7168
7169
7170
7171
7172
7173
7174
7175

7176
7177
7178
7179
7180
7181
7182
7183
7184
7185

7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200


7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213

7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227

7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240

7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
7252
7253

7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269

7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284

7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299

7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315

7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335

7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355

7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376

7377
7378

7379
7380

7381
7382
7383
7384
7385
7386
7387
7168
7169
7170
7171
7172
7173
7174

7175
7176
7177
7178
7179
7180
7181
7182
7183
7184

7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198


7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212

7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226

7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239

7240
7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
7252

7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268

7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283

7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298

7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314

7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334

7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354

7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375

7376
7377

7378
7379

7380
7381
7382
7383
7384
7385
7386
7387







-
+









-
+













-
-
+
+












-
+













-
+












-
+












-
+















-
+














-
+














-
+















-
+



















-
+



















-
+




















-
+

-
+

-
+







} -result {}
test text-31.4 {peer widgets} -body {
    toplevel .top
    pack [text .t]
    for {set i 1} {$i < 20} {incr i} {
	   .t insert end "Line $i\n"
    }
    pack [.t peer create .top.t -start 5 -end 11]
    pack [.t peer create .top.t -startline 5 -endline 11]
    update
    destroy .t .top
} -result {}
test text-31.5 {peer widgets} -body {
    toplevel .top
    pack [text .t]
    for {set i 1} {$i < 20} {incr i} {
	   .t insert end "Line $i\n"
    }
    pack [.t peer create .top.t -start 5 -end 11]
    pack [.t peer create .top.t -startline 5 -endline 11]
    pack [.top.t peer create .top.t2]
    set res [list [.top.t index end] [.top.t2 index end]]
    update
    return $res
} -cleanup {
    destroy .t .top
} -result {7.0 7.0}
test text-31.6 {peer widgets} -body {
    toplevel .top
    pack [text .t]
    for {set i 1} {$i < 20} {incr i} {
	   .t insert end "Line $i\n"
    }
    pack [.t peer create .top.t -start 5 -end 11]
    pack [.top.t peer create .top.t2 -start {} -end {}]
    pack [.t peer create .top.t -startline 5 -endline 11]
    pack [.top.t peer create .top.t2 -startline {} -endline {}]
    set res [list [.top.t index end] [.top.t2 index end]]
    update
    return $res
} -cleanup {
    destroy .t .top
} -result {7.0 21.0}
test text-31.7 {peer widgets} -body {
    toplevel .top
    pack [text .t]
    for {set i 1} {$i < 20} {incr i} {
	   .t insert end "Line $i\n"
    }
    pack [.t peer create .top.t -start 5 -end 11]
    pack [.t peer create .top.t -startline 5 -endline 11]
    update ; update
    set p1 [.top.t count -update -ypixels 1.0 end]
    set p2 [.t count -update -ypixels 5.0 11.0]
    expr {$p1 eq $p2}
} -cleanup {
    destroy .t .top
} -result 1
test text-31.8 {peer widgets} -body {
    toplevel .top
    pack [text .t]
    for {set i 1} {$i < 20} {incr i} {
	   .t insert end "Line $i\n"
    }
    pack [.t peer create .top.t -start 5 -end 11]
    pack [.t peer create .top.t -startline 5 -endline 11]
    update ; update
    .t delete 3.0 6.0
    .top.t index end
} -cleanup {
    destroy .t .top
} -result {6.0}
test text-31.9 {peer widgets} -body {
    toplevel .top
    pack [text .t]
    for {set i 1} {$i < 20} {incr i} {
	   .t insert end "Line $i\n"
    }
    pack [.t peer create .top.t -start 5 -end 11]
    pack [.t peer create .top.t -startline 5 -endline 11]
    update ; update
    .t delete 8.0 12.0
    .top.t index end
} -cleanup {
    destroy .t .top
} -result {4.0}
test text-31.10 {peer widgets} -body {
    toplevel .top
    pack [text .t]
        for {set i 1} {$i < 20} {incr i} {
        .t insert end "Line $i\n"
    }
    pack [.t peer create .top.t -start 5 -end 11]
    pack [.t peer create .top.t -startline 5 -endline 11]
    update ; update
    .t delete 3.0 13.0
    .top.t index end
} -cleanup {
    destroy .t .top
} -result {1.0}
test text-31.11 {peer widgets} -setup {
    pack [text .t]
    set res {}
} -body {
    for {set i 1} {$i < 100} {incr i} {
        .t insert end "Line $i\n"
    }
    .t tag add sel 1.0 end-1c
    lappend res [.t tag ranges sel]
    .t configure -start 10 -end 20
    .t configure -startline 10 -endline 20
    lappend res [.t tag ranges sel]
    return $res
} -cleanup {
    destroy .t
} -result {{1.0 100.0} {1.0 11.0}}
test text-31.12 {peer widgets} -setup {
    pack [text .t]
    set res {}
} -body {
    for {set i 1} {$i < 100} {incr i} {
	   .t insert end "Line $i\n"
    }
    .t tag add sel 1.0 end-1c
    lappend res [.t tag ranges sel]
    .t configure -start 11
    .t configure -startline 11
    lappend res [.t tag ranges sel]
    return $res
} -cleanup {
    destroy .t
} -result {{1.0 100.0} {1.0 90.0}}
test text-31.13 {peer widgets} -setup {
    pack [text .t]
    set res {}
} -body {
    for {set i 1} {$i < 100} {incr i} {
	   .t insert end "Line $i\n"
    }
    .t tag add sel 1.0 end-1c
    lappend res [.t tag ranges sel]
    .t configure -end 90
    .t configure -endline 90
    lappend res [.t tag ranges sel]
    destroy .t
    return $res
} -cleanup {
    destroy .t
} -result {{1.0 100.0} {1.0 90.0}}
test text-31.14 {peer widgets} -setup {
    pack [text .t]
    set res {}
} -body {
    for {set i 1} {$i < 20} {incr i} {
	   .t insert end "Line $i\n"
    }
    .t tag add sel 1.0 3.0 5.0 7.0 9.0 11.0 13.0 15.0 17.0 19.0
    lappend res [.t tag prevrange sel 1.0]
    .t configure -start 6 -end 12
    .t configure -startline 6 -endline 12
    lappend res [.t tag ranges sel]
    lappend res "next" [.t tag nextrange sel 4.0] \
      [.t tag nextrange sel 5.0] [.t tag nextrange sel 6.0] \
      [.t tag nextrange sel 7.0]
    lappend res "prev" [.t tag prevrange sel 1.0] \
      [.t tag prevrange sel 2.0] [.t tag prevrange sel 3.0] \
      [.t tag prevrange sel 4.0]
    return $res
} -cleanup {
    destroy .t
} -result {{} {1.0 2.0 4.0 6.0} next {4.0 6.0} {} {} {} prev {} {1.0 2.0} {1.0 2.0} {1.0 2.0}}
test text-31.15 {peer widgets} -setup {
    pack [text .t]
    set res {}
} -body {
    for {set i 1} {$i < 20} {incr i} {
	   .t insert end "Line $i\n"
    }
    .t tag add sel 1.0 3.0 9.0 11.0 13.0 15.0 17.0 19.0
    .t configure -start 6 -end 12
    .t configure -startline 6 -endline 12
    lappend res [.t tag ranges sel]
    lappend res "next" [.t tag nextrange sel 4.0] \
      [.t tag nextrange sel 5.0] [.t tag nextrange sel 6.0] \
      [.t tag nextrange sel 7.0]
    lappend res "prev" [.t tag prevrange sel 1.0] \
      [.t tag prevrange sel 2.0] [.t tag prevrange sel 3.0] \
      [.t tag prevrange sel 4.0]
    return $res
} -cleanup {
    destroy .t
} -result {{4.0 6.0} next {4.0 6.0} {} {} {} prev {} {} {} {}}
test text-31.16 {peer widgets} -setup {
    pack [text .t]
    set res {}
} -body {
    for {set i 1} {$i < 20} {incr i} {
	.t insert end "Line $i\n"
    }
    .t tag add sel 1.0 7.0 9.0 11.0 13.0 15.0 17.0 19.0
    .t configure -start 6 -end 12
    .t configure -startline 6 -endline 12
    lappend res [.t tag ranges sel]
    lappend res "next" [.t tag nextrange sel 4.0] \
      [.t tag nextrange sel 5.0] [.t tag nextrange sel 6.0] \
      [.t tag nextrange sel 7.0]
    lappend res "prev" [.t tag prevrange sel 1.0] \
      [.t tag prevrange sel 2.0] [.t tag prevrange sel 3.0] \
      [.t tag prevrange sel 4.0]
    return $res
} -cleanup {
    destroy .t
} -result {{1.0 2.0 4.0 6.0} next {4.0 6.0} {} {} {} prev {} {1.0 2.0} {1.0 2.0} {1.0 2.0}}
test text-31.17 {peer widgets} -setup {
    pack [text .t]
    set res {}
} -body {
    for {set i 1} {$i < 20} {incr i} {
	   .t insert end "Line $i\n"
    }
    .t tag add sel 1.0 11.0
    lappend res [.t tag ranges sel]
    lappend res [catch {.t configure -start 15 -end 10}]
    lappend res [catch {.t configure -startline 15 -endline 10}]
    lappend res [.t tag ranges sel]
    .t configure -start 6 -end 12
    .t configure -startline 6 -endline 12
    lappend res [.t tag ranges sel]
    .t configure -start {} -end {}
    .t configure -startline {} -endline {}
    lappend res [.t tag ranges sel]
    return $res
} -cleanup {
    destroy .t
} -result {{1.0 11.0} 1 {1.0 11.0} {1.0 6.0} {1.0 11.0}}
test text-31.18 {peer widgets} -setup {
    pack [text .t]
7442
7443
7444
7445
7446
7447
7448
7449

7450
7451
7452
7453
7454
7455
7456
7442
7443
7444
7445
7446
7447
7448

7449
7450
7451
7452
7453
7454
7455
7456







-
+







    set after [$w count -ypixels 1.0 2.0]
    destroy .g
    expr {$before eq $after}
} -cleanup {
    destroy .t
} -result 1

test text-32.2 {peer widget -start, -end and deletion (bug 1630262)} -setup {
test text-32.2 {peer widget -start, -endline and deletion (bug 1630262)} -setup {
    destroy .t .pt
    set res {}
} -body {
    text .t
    .t peer create .pt
    for {set i 1} {$i < 100} {incr i} {
      .t insert end "Line $i\n"
7472
7473
7474
7475
7476
7477
7478
7479

7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500

7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7472
7473
7474
7475
7476
7477
7478

7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499

7500






























































































7501
7502
7503
7504
7505
7506
7507







-
+




















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







    .pt delete 2.0 end
    # this test succeeds provided there is no crash
    set res 1
} -cleanup {
    destroy .pt
} -result 1

test text-32.3 {peer widget -start, -end and deletion (bug 1630262)} -setup {
test text-32.3 {peer widget -start, -endline and deletion (bug 1630262)} -setup {
    destroy .t .pt
    set res {}
} -body {
    text .t
    .t peer create .pt
    for {set i 1} {$i < 100} {incr i} {
      .t insert end "Line $i\n"
    }
    .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]
} -cleanup {
    destroy .pt
} -result {4 3}

test text-32.4 {peer widget -start, -end and deletion (bug 1630262)} -setup {
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
    for {set i 1} {$i < 100} {incr i} {
      .t insert end "Line $i\n"
    }
    .t configure -startline 5 -endline 15
    .pt configure -startline 8 -endline 12
    # .pt now shows a range entirely inside the range of .pt
    # from .t, delete lines located after [.pt cget -end]
    .t delete 9.0 10.0
    # from .t, delete lines straddling [.pt cget -end]
    .t delete 6.0 9.0
    lappend res [.t cget -start] [.t cget -end] [.pt cget -start] [.pt cget -end]
    .t configure -startline 5 -endline 12
    .pt configure -startline 8 -endline 12
    # .pt now shows again a range entirely inside the range of .pt
    # from .t, delete lines located before [.pt cget -start]
    .t delete 2.0 3.0
    # from .t, delete lines straddling [.pt cget -start]
    .t delete 2.0 5.0
    lappend res [.t cget -start] [.t cget -end] [.pt cget -start] [.pt cget -end]
    .t configure -startline 22 -endline 31
    .pt configure -startline 42 -endline 51
    # .t now shows a range entirely before the range of .pt
    # from .t, delete some lines, then do it from .pt
    .t delete 2.0 3.0
    .t delete 2.0 5.0
    .pt delete 2.0 5.0
    lappend res [.t cget -start] [.t cget -end] [.pt cget -start] [.pt cget -end]
    .t configure -startline 55 -endline 75
    .pt configure -startline 60 -endline 70
    # .pt now shows a range entirely inside the range of .t
    # from .t, delete a range straddling the entire range of .pt
    .t delete 3.0 18.0
    lappend res [.t cget -start] [.t cget -end] [.pt cget -start] [.pt cget -end]
} -cleanup {
    destroy .pt .t
} -result {5 11 8 10 5 8 6 8 22 27 38 44 55 60 57 57}

test text-32.2 {peer widget -start, -end and deletion (bug 1630262)} -setup {
    destroy .t .pt
    set res {}
} -body {
    text .t
    .t peer create .pt
    for {set i 1} {$i < 100} {incr i} {
      .t insert end "Line $i\n"
    }
    .t configure -startline 5
    # none of the following delete shall crash
    # (all did before fixing bug 1630262)
    # 1. delete on the same line: line1 == line2 in DeleteIndexRange,
    #    and resetView is true neither for .t not for .pt
    .pt delete 2.0 2.2
    # 2. delete just one line: line1 < line2 in DeleteIndexRange,
    #    and resetView is true only for .t, not for .pt
    .pt delete 2.0 3.0
    # 3. delete several lines: line1 < line2 in DeleteIndexRange,
    #    and resetView is true only for .t, not for .pt
    .pt delete 2.0 5.0
    # 4. delete to the end line: line1 < line2 in DeleteIndexRange,
    #    and resetView is true only for .t, not for .pt
    .pt delete 2.0 end
    # this test succeeds provided there is no crash
    set res 1
} -cleanup {
    destroy .pt
} -result 1

test text-32.3 {peer widget -start, -end and deletion (bug 1630262)} -setup {
    destroy .t .pt
    set res {}
} -body {
    text .t
    .t peer create .pt
    for {set i 1} {$i < 100} {incr i} {
      .t insert end "Line $i\n"
    }
    .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]
} -cleanup {
    destroy .pt
} -result {4 3}

test text-32.4 {peer widget -start, -end and deletion (bug 1630262)} -setup {
    destroy .t .pt
    set res {}
} -body {
    text .t
    .t peer create .pt
    for {set i 1} {$i < 100} {incr i} {
      .t insert end "Line $i\n"
7648
7649
7650
7651
7652
7653
7654
7655

7656
7657
7658
7659
7660
7661
7662
7554
7555
7556
7557
7558
7559
7560

7561
7562
7563
7564
7565
7566
7567
7568







-
+







    .t peer names foo
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t peer names"}
test text-33.3 {TextWidgetCmd procedure, "peer" option} -setup {
    text .t
} -body {
    .t pee names
    .t peer names
} -cleanup {
    destroy .t
} -returnCodes {ok} -result {}
test text-33.4 {TextWidgetCmd procedure, "peer" option} -setup {
    text .t
} -body {
    .t peer names
7680
7681
7682
7683
7684
7685
7686
7687

7688
7689
7690
7691

7692
7693
7694
7695
7696
7697

7698
7699
7700
7701
7702
7703
7704
7705
7706

7707
7708
7709
7710
7711
7712
7713
7714
7715
7716

7717
7718

7719
7720

7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732

7733
7734

7735
7736

7737
7738
7739
7740
7741
7742
7743

7744
7745
7746
7747
7748
7749
7750
7751
7752

7753
7754

7755
7756

7757
7758

7759
7760

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
7586
7587
7588
7589
7590
7591
7592

7593
7594
7595
7596

7597
7598
7599
7600
7601
7602

7603
7604
7605
7606
7607
7608
7609
7610
7611

7612
7613
7614
7615
7616
7617
7618
7619
7620
7621

7622
7623

7624
7625

7626
7627
7628
7629
7630
7631
7632
7633
7634
7635
7636
7637

7638
7639

7640
7641

7642
7643
7644
7645
7646
7647
7648

7649
7650
7651
7652
7653
7654
7655
7656
7657

7658
7659

7660
7661

7662
7663

7664
7665

7666
7667

7668
7669
7670
7671
7672
7673
7674
7675
7676

7677
7678
7679
7680
7681
7682
7683
7684
7685
7686
7687
7688
7689

7690
7691
7692
7693
7694
7695
7696
7697
7698
7699
7700
7701
7702

7703
7704
7705
7706
7707
7708
7709







-
+



-
+





-
+








-
+









-
+

-
+

-
+











-
+

-
+

-
+






-
+








-
+

-
+

-
+

-
+

-
+

-
+








-













-













-







    destroy .t2
    lappend res [.t peer names]
} -cleanup {
    destroy .t
} -result {.t2 .t {}}
test text-33.7 {peer widget -start, -end} -body {
    text .t
    set res [.t configure -start 10 -end 5]
    set res [.t configure -startline 10 -endline 5]
    return $res
} -cleanup {
    destroy .t
} -returnCodes {2} -result {}
} -returnCodes 2 -result {}
test text-33.8 {peer widget -start, -end} -body {
    text .t
    for {set i 1} {$i < 100} {incr i} {
	   .t insert end "Line $i\n"
    }
    .t configure -start 10 -end 5
    .t configure -startline 10 -endline 5
} -cleanup {
    destroy .t
} -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 -start 5 -end 10
    .t configure -startline 5 -endline 10
} -cleanup {
    destroy .t
} -returnCodes {ok} -result {}
test text-33.10 {peer widget -start, -end} -body {
    text .t
    for {set i 1} {$i < 100} {incr i} {
	   .t insert end "Line $i\n"
    }
    set res [.t index end]
    lappend res [catch {.t configure -start 5 -end 10 -tab foo}]
    lappend res [catch {.t configure -startline 5 -endline 10 -tab foo}]
    lappend res [.t index end]
    lappend res [catch {.t configure -tab foo -start 15 -end 20}]
    lappend res [catch {.t configure -tab foo -startline 15 -endline 20}]
    lappend res [.t index end]
    .t configure -start {} -end {}
    .t configure -startline {} -endline {}
    lappend res [.t index end]
    return $res
} -cleanup {
    destroy .t
} -result {101.0 1 101.0 1 101.0 101.0}
test text-33.11 {peer widget -start, -end} -body {
    text .t
    for {set i 1} {$i < 100} {incr i} {
	   .t insert end "Line $i\n"
    }
    set res [.t index end]
    lappend res [catch {.t configure -start 5 -end 15}]
    lappend res [catch {.t configure -startline 5 -endline 15}]
    lappend res [.t index end]
    lappend res [catch {.t configure -start 10 -end 40}]
    lappend res [catch {.t configure -startline 10 -endline 40}]
    lappend res [.t index end]
    .t configure -start {} -end {}
    .t configure -startline {} -endline {}
    lappend res [.t index end]
    return $res
} -cleanup {
    destroy .t
} -result {101.0 0 11.0 0 31.0 101.0}

test text-34.1 {peer widget -start, -end and selection} -setup {
test text-34.1 {peer widget -start, -endline and selection} -setup {
    text .t
    set res {}
} -body {
    for {set i 1} {$i < 100} {incr i} {
	   .t insert end "Line $i\n"
    }
    .t tag add sel 10.0 20.0
    lappend res [.t tag ranges sel]
    .t configure -start 5 -end 30
    .t configure -startline 5 -endline 30
    lappend res [.t tag ranges sel]
    .t configure -start 5 -end 15
    .t configure -startline 5 -endline 15
    lappend res [.t tag ranges sel]
    .t configure -start 15 -end 30
    .t configure -startline 15 -endline 30
    lappend res [.t tag ranges sel]
    .t configure -start 15 -end 16
    .t configure -startline 15 -endline 16
    lappend res [.t tag ranges sel]
    .t configure -start 25 -end 30
    .t configure -startline 25 -endline 30
    lappend res [.t tag ranges sel]
    .t configure -start {} -end {}
    .t configure -startline {} -endline {}
    lappend res [.t tag ranges sel]
    return $res
} -cleanup {
    destroy .t
} -result {{10.0 20.0} {6.0 16.0} {6.0 11.0} {1.0 6.0} {1.0 2.0} {} {10.0 20.0}}

test text-35.1 {widget dump -command alters tags} -setup {
     proc Dumpy {key value index} {
#puts "KK: $key, $value"
      .t tag add $value [list $index linestart] [list $index lineend]
    }
    text .t
} -body {
    .t insert end "abc\n" a "---" {} "def" b "   \n" {} "ghi\n" c
    .t tag configure b -background red
    .t dump -all -command Dumpy 1.0 end
    set result "ok"
} -cleanup {
    destroy .t
} -result {ok}
test text-35.2 {widget dump -command makes massive changes} -setup {
    proc Dumpy {key value index} {
#puts "KK: $key, $value"
      .t delete 1.0 end
    }
    text .t
} -body {
    .t insert end "abc\n" a "---" {} "def" b "   \n" {} "ghi\n" c
    .t tag configure b -background red
    .t dump -all -command Dumpy 1.0 end
    set result "ok"
} -cleanup {
    destroy .t
} -result {ok}
test text-35.3 {widget dump -command destroys widget} -setup {
    proc Dumpy {key value index} {
#puts "KK: $key, $value"
        destroy .t
    }
    text .t
} -body {
    .t insert end "abc\n" a "---" {} "def" b "   \n" {} "ghi\n" c
    .t tag configure b -background red
    .t dump -all -command Dumpy 1.0 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 (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

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
1
2
3



4
5
6
7
8

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42



-
-
-
+
+
+


-
+



+
+
+







+
+
+
+
+



+
+
+
+
+







# This file is a Tcl script to test the code in the file tkTextDisp.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.1
package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

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" }]

# Platform specific procedure for updating the text widget.

if {[tk windowingsystem] == "aqua"} {
    proc updateText {} {
	update idletasks
    }
    proc delay {} {
	update idletasks
	after 100
	update idletasks
    }
} else {
    proc updateText {} {
	update
    }
    proc delay {} {
	update
	after 100
	update
    }
}

# The procedure below is used as the scrolling command for the text;
# it just saves the scrolling information in a variable "scrollInfo".

proc scroll args {
209
210
211
212
213
214
215
216

217
218

219
220
221
222
223
224
225
226

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

229
230

231
232
233
234
235
236
237
238

239
240
241
242
243
244
245
246







-
+

-
+







-
+







    destroy .txt
} {}

test textDisp-1.1 {GetStyle procedure, priorities and tab stops} {
    .t delete 1.0 end
    .t insert 1.0 "x\ty"
    .t tag delete x y z
    .t tag configure x -tabs {50}
    .t tag configure x -tabs 50
    .t tag configure y -foreground black
    .t tag configure z -tabs {70}
    .t tag configure z -tabs 70
    .t tag add x 1.0 1.end
    .t tag add y 1.0 1.end
    .t tag add z 1.0 1.end
    update idletasks
    set x [lindex [.t bbox 1.2] 0]
    .t tag configure z -tabs {}
    lappend x [lindex [.t bbox 1.2] 0]
    .t tag configure z -tabs {30}
    .t tag configure z -tabs 30
    .t tag raise x
    update idletasks
    lappend x [lindex [.t bbox 1.2] 0]
} [list 75 55 55]
.t tag delete x y z
test textDisp-1.2 {GetStyle procedure, wrapmode} {textfonts} {
    .t configure -wrap char
271
272
273
274
275
276
277
278

279
280
281
282
283
284
285
284
285
286
287
288
289
290

291
292
293
294
295
296
297
298







-
+







} [list [list 138 5 7 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-2.5 {LayoutDLine, word wrap} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This isx some sample text for testing."
    list [.t bbox 1.13] [.t bbox 1.19] [.t bbox 1.20] [.t bbox 1.21]
} [list [list 96 5 $fixedWidth $fixedHeight] [list 138 5 $fixedWidth $fixedHeight] [list 145 5 0  $fixedHeight] [list 5 [expr {$fixedDiff + 18}] $fixedWidth $fixedHeight]]
test textDisp-2.6 {LayoutDLine, word wrap} {
test textDisp-2.6 {LayoutDLine, word wrap} failsOnUbuntu {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This isxxx some sample text for testing."
    list [.t bbox 1.15] [.t bbox 1.16]
} [list [list 110 5 35 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-2.7 {LayoutDLine, marks and tags} {textfonts} {
    .t configure -wrap word
490
491
492
493
494
495
496
497

498
499
500
501
502
503
504
503
504
505
506
507
508
509

510
511
512
513
514
515
516
517







-
+







    .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}
} 75
test textDisp-2.25 {LayoutDLine, tabs, breaking chunks at tabs} {textfonts} {
    .t delete 1.0 end
    .t tag delete x
    .t tag configure x -tabs [list 30 60 90 120]
    .t insert 1.0 "a\tb\tc\td\te"
    .t mark set dummy1 1.1
    .t mark set dummy2 1.2
657
658
659
660
661
662
663
664

665
666
667
668
669
670
671
670
671
672
673
674
675
676

677
678
679
680
681
682
683
684







-
+







    .t yview 16.0
    updateText
    set x [list [.t index @0,0] $tk_textRelayout $tk_textRedraw]
    wm overrideredirect . 0
    updateText
    set x
} {8.0 {16.0 17.0 15.0 14.0 13.0 12.0 11.0 10.0 9.0 8.0} {8.0 9.0 10.0 11.0 12.0 13.0 14.0 15.0 16.0 17.0}}
test textDisp-4.8 {UpdateDisplayInfo, filling in extra vertical space} {
test textDisp-4.8 {UpdateDisplayInfo, filling in extra vertical space} failsOnXQuarz {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17"
    .t yview 16.0
    updateText
    .t delete 5.0 14.0
    updateText
    set x [list [.t index @0,0] $tk_textRelayout $tk_textRedraw]
704
705
706
707
708
709
710
711

712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727

728
729
730
731
732
733
734
717
718
719
720
721
722
723

724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739

740
741
742
743
744
745
746
747







-
+















-
+







    .t yview moveto 1
    updateText
    .t yview moveto 0
    updateText
    .t yview moveto 1
    updateText
    winfo ismapped .b
} {0}
} 0
.t configure -wrap word
.t delete 1.0 end
.t insert end "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7\n"
.t insert end "Line 8\nLine 9\nLine 10\nLine 11\nLine 12\nLine 13\n"
.t insert end "Line 14\nLine 15\nLine 16"
.t tag delete x
.t tag configure x -relief raised -borderwidth 2 -background white
test textDisp-4.13 {UpdateDisplayInfo, special handling for top/bottom lines} {
    .t tag add x 1.0 end
    .t yview 1.0
    updateText
    .t yview scroll 3 units
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{11.0 12.0 13.0} {4.0 10.0 11.0 12.0 13.0}}
test textDisp-4.14 {UpdateDisplayInfo, special handling for top/bottom lines} {
test textDisp-4.14 {UpdateDisplayInfo, special handling for top/bottom lines} failsOnXQuarz {
    .t tag remove x 1.0 end
    .t yview 1.0
    updateText
    .t yview scroll 3 units
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{11.0 12.0 13.0} {11.0 12.0 13.0}}
853
854
855
856
857
858
859
860

861
862
863
864
865
866
867
866
867
868
869
870
871
872

873
874
875
876
877
878
879
880







-
+







    bind .t.f <Configure> {.t.f configure -width 30 -height 30}
    .t window create insert -window .t.f
    updateText
    list [winfo width .t.f] [winfo height .t.f]
} [list 30 30]

.t configure -wrap char
test textDisp-6.1 {scrolling in DisplayText, scroll up} {
test textDisp-6.1 {scrolling in DisplayText, scroll up} failsOnXQuarz {
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 2.0 3.0
1141
1142
1143
1144
1145
1146
1147
1148

1149
1150
1151
1152
1153
1154
1155
1154
1155
1156
1157
1158
1159
1160

1161
1162
1163
1164
1165
1166
1167
1168







-
+







	.t insert end "\nLine $i"
    }
    updateText
    .t delete 1.41 1.44
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{1.0 1.20 1.40} {1.0 1.20 1.40}}
test textDisp-8.7 {TkTextChanged} {
test textDisp-8.7 {TkTextChanged} failsOnXQuarz {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 1.2 1.end
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
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







-
+










-
+







	.t insert end "\nLine $i"
    }
    updateText
    .t delete 2.2
    updateText
    list $tk_textRelayout $tk_textRedraw
} {2.0 2.0}
test textDisp-8.9 {TkTextChanged} {
test textDisp-8.9 {TkTextChanged} failsOnXQuarz {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 2.0 3.0
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 8.0} {2.0 8.0}}
test textDisp-8.10 {TkTextChanged} {
test textDisp-8.10 {TkTextChanged} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 2.19
    updateText
    .t delete 2.19
    updateText
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
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







-
+

















-
+










-
+










-
+










-
+










-
+







    .t insert 1.0 \nLine2\nLine3\n
    updateText
    .t insert 3.0 ""
    .t delete 1.0 2.0
    update idletasks
} {}

test textDisp-9.1 {TkTextRedrawTag} {
test textDisp-9.1 {TkTextRedrawTag} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    updateText
    .t tag add big 2.2 2.4
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.18} {2.0 2.18}}
test textDisp-9.2 {TkTextRedrawTag} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    updateText
    .t tag add big 1.2 2.4
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{1.0 2.0 2.17} {1.0 2.0 2.17}}
test textDisp-9.3 {TkTextRedrawTag} {
test textDisp-9.3 {TkTextRedrawTag} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    updateText
    .t tag add big 2.2 2.4
    updateText
    .t tag remove big 1.0 end
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20} {2.0 2.20 eof}}
test textDisp-9.4 {TkTextRedrawTag} {
test textDisp-9.4 {TkTextRedrawTag} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    updateText
    .t tag add big 2.2 2.20
    updateText
    .t tag remove big 1.0 end
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20} {2.0 2.20 eof}}
test textDisp-9.5 {TkTextRedrawTag} {
test textDisp-9.5 {TkTextRedrawTag} {failsOnUbuntu failsOnXQuarz} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    updateText
    .t tag add big 2.2 2.end
    updateText
    .t tag remove big 1.0 end
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20} {2.0 2.20 eof}}
test textDisp-9.6 {TkTextRedrawTag} {
test textDisp-9.6 {TkTextRedrawTag} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap"
    updateText
    .t tag add big 2.2 3.5
    updateText
    .t tag remove big 1.0 end
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20 3.0 3.20} {2.0 2.20 3.0 3.20 eof}}
test textDisp-9.7 {TkTextRedrawTag} {
test textDisp-9.7 {TkTextRedrawTag} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 2.19
    updateText
    .t tag remove big 2.19
    updateText
1332
1333
1334
1335
1336
1337
1338
1339

1340
1341
1342
1343

1344
1345
1346
1347
1348
1349
1350
1345
1346
1347
1348
1349
1350
1351

1352
1353
1354
1355

1356
1357
1358
1359
1360
1361
1362
1363







-
+



-
+







} {2.0 2.17}
test textDisp-9.10 {TkTextRedrawTag} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 1.0 2.0
    updateText
    set tk_textRedraw {none}
    set tk_textRedraw none
    .t tag add big 1.3 1.5
    updateText
    set tk_textRedraw
} {none}
} none
test textDisp-9.11 {TkTextRedrawTag} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 1.0 2.0
    updateText
    .t tag add big 1.0 2.0
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
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







-
+













-
+







}
updateText
test textDisp-11.1 {TkTextSetYView} {
    .t yview 30.0
    updateText
    .t index @0,0
} {30.0}
test textDisp-11.2 {TkTextSetYView} {
test textDisp-11.2 {TkTextSetYView} failsOnXQuarz {
    .t yview 30.0
    updateText
    .t yview 32.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {32.0 {40.0 41.0}}
test textDisp-11.3 {TkTextSetYView} {
    .t yview 30.0
    updateText
    .t yview 28.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {28.0 {28.0 29.0}}
test textDisp-11.4 {TkTextSetYView} {
test textDisp-11.4 {TkTextSetYView} failsOnXQuarz {
    .t yview 30.0
    updateText
    .t yview 31.4
    updateText
    list [.t index @0,0] $tk_textRedraw
} {31.0 40.0}
test textDisp-11.5 {TkTextSetYView} {
1481
1482
1483
1484
1485
1486
1487
1488

1489
1490
1491
1492
1493
1494
1495
1496

1497
1498
1499
1500
1501
1502
1503
1494
1495
1496
1497
1498
1499
1500

1501
1502
1503
1504
1505
1506
1507
1508

1509
1510
1511
1512
1513
1514
1515
1516







-
+







-
+







    .t yview 30.0
    updateText
    set tk_textRedraw {}
    .t yview -pickplace 26.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {21.0 {21.0 22.0 23.0 24.0 25.0 26.0 27.0 28.0 29.0}}
test textDisp-11.8 {TkTextSetYView} {
test textDisp-11.8 {TkTextSetYView} failsOnXQuarz {
    .t yview 30.0
    updateText
    set tk_textRedraw {}
    .t yview -pickplace 41.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {32.0 {40.0 41.0}}
test textDisp-11.9 {TkTextSetYView} {
test textDisp-11.9 {TkTextSetYView} failsOnXQuarz {
    .t yview 30.0
    updateText
    set tk_textRedraw {}
    .t yview -pickplace 43.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {38.0 {40.0 41.0 42.0 43.0 44.0 45.0 46.0 47.0 48.0}}
1513
1514
1515
1516
1517
1518
1519
1520

1521
1522
1523
1524
1525
1526
1527
1526
1527
1528
1529
1530
1531
1532

1533
1534
1535
1536
1537
1538
1539
1540







-
+







    .t yview 195.0
    updateText
    set tk_textRedraw {}
    .t yview 197.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {191.0 {191.0 192.0 193.0 194.0 195.0 196.0}}
test textDisp-11.12 {TkTextSetYView, wrapped line is off-screen} {
test textDisp-11.12 {TkTextSetYView, wrapped line is off-screen} failsOnXQuarz {
    .t insert 10.0 "Long line with enough text to wrap\n"
    .t yview 1.0
    updateText
    set tk_textRedraw {}
    .t see 10.30
    updateText
    list [.t index @0,0] $tk_textRedraw
1814
1815
1816
1817
1818
1819
1820
1821

1822
1823
1824
1825
1826
1827
1828
1827
1828
1829
1830
1831
1832
1833

1834
1835
1836
1837
1838
1839
1840
1841







-
+







    .top2.t2 insert "1.0 lineend" ç
    .top2.t2 see "1.0 lineend"
    updateText
    set new [.top2.t2 index @0,0]
    set res [.top2.t2 compare $ref == $new]
    destroy .top2
    set res
} {0}
} 0
wm geom . {}

.t configure -wrap none
test textDisp-14.1 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    updateText
    .t insert end xxxxxxxxx\n
1854
1855
1856
1857
1858
1859
1860
1861

1862
1863
1864
1865
1866
1867
1868
1867
1868
1869
1870
1871
1872
1873

1874
1875
1876
1877
1878
1879
1880
1881







-
+







} {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} {
test textDisp-14.7 {TkTextXviewCmd procedure} failsOnUbuntu {
    .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 .3
    .t xview
} [list [expr {118.0/392}] [expr {258.0/392}]]
1886
1887
1888
1889
1890
1891
1892
1893

1894
1895
1896
1897
1898
1899
1900
1899
1900
1901
1902
1903
1904
1905

1906
1907
1908
1909
1910
1911
1912
1913







-
+







    list [catch {.t xview scroll a} msg] $msg
} {1 {wrong # args: should be ".t xview scroll number pages|pixels|units"}}
test textDisp-14.11 {TkTextXviewCmd procedure} {
    list [catch {.t xview scroll a b c} msg] $msg
} {1 {wrong # args: should be ".t xview scroll number pages|pixels|units"}}
test textDisp-14.12 {TkTextXviewCmd procedure} {
    list [catch {.t xview scroll gorp units} msg] $msg
} {1 {expected integer but got "gorp"}}
} {1 {expected floating-point number but got "gorp"}}
test textDisp-14.13 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end "a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9\n"
    .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx"
    .t xview moveto 0
    .t xview scroll 2 pa
2003
2004
2005
2006
2007
2008
2009
2010

2011
2012
2013
2014
2015
2016
2017
2016
2017
2018
2019
2020
2021
2022

2023
2024
2025
2026
2027
2028
2029
2030







-
+







    # 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}
} 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"
}
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
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







-
+











-
+



-
+



-
+





-
+







} {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} {
test textDisp-16.11 {TkTextYviewCmd procedure, "moveto" option} failsOnUbuntu {
    .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} {
test textDisp-16.14 {TkTextYviewCmd procedure, "moveto" option} failsOnUbuntu {
    .t yview moveto .75
    .t index @0,0
} {151.60}
test textDisp-16.15 {TkTextYviewCmd procedure, "moveto" option} {
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} {
test textDisp-16.16 {TkTextYviewCmd procedure, "moveto" option} textfonts {
    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} {
test textDisp-16.17 {TkTextYviewCmd procedure, "moveto" option} failsOnUbuntu {
    .t yview moveto .755
    .t index @0,0
} {151.80}
test textDisp-16.18 {TkTextYviewCmd procedure, "moveto" roundoff} {textfonts} {
    catch {destroy .top1}
    toplevel .top1
    wm geometry .top1 +0+0
2105
2106
2107
2108
2109
2110
2111
2112

2113
2114
2115
2116


2117
2118
2119
2120
2121
2122
2123
2118
2119
2120
2121
2122
2123
2124

2125
2126
2127


2128
2129
2130
2131
2132
2133
2134
2135
2136







-
+


-
-
+
+







test textDisp-16.19 {TkTextYviewCmd procedure, "scroll" option} {
    list [catch {.t yview scroll a} msg] $msg
} {1 {wrong # args: should be ".t yview scroll number pages|pixels|units"}}
test textDisp-16.20 {TkTextYviewCmd procedure, "scroll" option} {
    list [catch {.t yview scroll a b c} msg] $msg
} {1 {wrong # args: should be ".t yview scroll number pages|pixels|units"}}
test textDisp-16.21 {TkTextYviewCmd procedure, "scroll" option} {
    list [catch {.t yview scroll badInt bogus} msg] $msg
    list [catch {.t yview scroll bogus bogus} msg] $msg
} {1 {bad argument "bogus": must be pages, pixels, or units}}
test textDisp-16.21.2 {TkTextYviewCmd procedure, "scroll" option} {
    list [catch {.t yview scroll badInt units} msg] $msg
} {1 {expected integer but got "badInt"}}
    list [catch {.t yview scroll bogus units} msg] $msg
} {1 {expected floating-point number but got "bogus"}}
test textDisp-16.22 {TkTextYviewCmd procedure, "scroll" option, back pages} {
    .t yview 50.0
    updateText
    .t yview scroll -1 pages
    .t index @0,0
} {42.0}
test textDisp-16.22.1 {TkTextYviewCmd procedure, "scroll" option, back pages} {
2163
2164
2165
2166
2167
2168
2169
2170

2171
2172
2173
2174
2175
2176
2177
2176
2177
2178
2179
2180
2181
2182

2183
2184
2185
2186
2187
2188
2189
2190







-
+







    updateText
    .t yview scroll 1 page
    set res [expr {int([.t index @0,0])}]
    if {$fixedDiff > 1} {
	incr res -1
    }
    set res
} {102}
} 102
test textDisp-16.29 {TkTextYviewCmd procedure, "scroll" option, forward pages} {
    .t configure -height 1
    updateText
    .t yview 50.0
    updateText
    .t yview scroll 1 pages
    set x [.t index @0,0]
2244
2245
2246
2247
2248
2249
2250
2251

2252
2253
2254
2255
2256
2257
2258
2257
2258
2259
2260
2261
2262
2263

2264
2265
2266
2267
2268
2269
2270
2271







-
+







} {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} {
test textDisp-16.40 {text count -xpixels} failsOnUbuntu {
    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"] \
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2498
2499
2500
2501
2502
2503
2504


2505
2506
2507
2508
2509
2510
2511







-
-







    (procedure "scrollError" line 2)
    invoked from within
"scrollError 0.0 1.0"
    (horizontal scrolling command executed by text)}}
catch {rename bgerror {}}
catch {rename bogus {}}
.t configure -xscrollcommand {} -yscrollcommand scroll

.t configure -xscrollcommand {} -yscrollcommand scroll
test textDisp-19.1 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    updateText
    set scrollInfo
} {0.0 1.0}
test textDisp-19.2 {GetYView procedure} {
2558
2559
2560
2561
2562
2563
2564
2565

2566
2567
2568
2569
2570
2571
2572
2569
2570
2571
2572
2573
2574
2575

2576
2577
2578
2579
2580
2581
2582
2583







-
+







	.t insert end "\nLine $i"
    }
    .t insert 2.end " is really quite long; in fact it's so long that it wraps three times"
    .t yview 2.26
    updateText
    set x $scrollInfo
} {0.125 0.75}
test textDisp-19.8 {GetYView procedure} {
test textDisp-19.8 {GetYView procedure} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    .t insert 10.end " is really quite long; in fact it's so long that it wraps three times"
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
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







-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+





-
+




-
+




-
+




-
+




-
+




















-
+







    .t yview insert
    updateText
    .t count -update -ypixels 1.0 end
    set scrollInfo
} {0.5 1.0}
test textDisp-19.11.2 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 1.0 end
} {20}
} 20
test textDisp-19.11.3 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines end 1.0
} {-20}
} -20
test textDisp-19.11.4 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 1.1 1.3
} {0}
} 0
test textDisp-19.11.5 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 16.1
} {0}
} 0
test textDisp-19.11.5.1 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 16.5
} {0}
} 0
test textDisp-19.11.6 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 16.24
} {1}
} 1
test textDisp-19.11.7 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 16.40
} {2}
} 2
test textDisp-19.11.8 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines "16.0 displaylineend +1c" "16.0 lineend"
} {3}
} 3
test textDisp-19.11.9 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 "16.0 lineend"
} {4}
} 4
test textDisp-19.11.10 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 "16.0 +4displaylines"
} {4}
} 4
test textDisp-19.11.11 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 "16.0 +2displaylines"
} {2}
} 2
test textDisp-19.11.12 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines "16.0 +1displayline" "16.0 +2displaylines -1c"
} {0}
} 0
.t tag configure elide -elide 1
test textDisp-19.11.13 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "16.0 +1displaylines" "16.0 +1displaylines +6c"
    .t count -displaylines 16.0 "16.0 +4displaylines"
} {4}
} 4
test textDisp-19.11.14 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "16.0 +1displaylines" "16.0 +1displaylines displaylineend"
    .t count -displaylines 16.0 "16.0 +4displaylines"
} {4}
} 4
test textDisp-19.11.15 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "16.0 +1displaylines" "16.0 +2displaylines"
    .t count -displaylines 16.0 "16.0 +4displaylines -1c"
} {3}
} 3
test textDisp-19.11.15a {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "16.0 +1displaylines" "16.0 +2displaylines"
    .t count -displaylines 16.0 "16.0 +4displaylines"
} {4}
} 4
test textDisp-19.11.16 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "14.0"
    .t count -displaylines 12.0 16.0
} {2}
} 2
test textDisp-19.11.17 {TextWidgetCmd procedure, "index +displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "14.0"
    list [.t index "11.5 +2d lines"] \
      [.t index "12.0 +2d lines"] [.t index "11.0 +2d lines"] \
      [.t index "13.0 +2d lines"] [.t index "13.1 +3d lines"] \
      [.t index "13.0 +4d lines"]
} {15.5 16.0 15.0 16.0 16.21 16.39}
test textDisp-19.11.18 {TextWidgetCmd procedure, "index +displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "14.0"
    list [.t index "15.5 -2d lines"] \
      [.t index "16.0 -2d lines"] [.t index "15.0 -2d lines"] \
      [.t index "16.0 -3d lines"] [.t index "16.23 -4d lines"] \
      [.t index "16.42 -5d lines"]
} {11.5 14.0 11.0 11.0 11.2 11.3}
test textDisp-19.11.19 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "16.0 +1displaylines"
    .t count -displaylines 12.0 17.0
} {4}
} 4
test textDisp-19.11.20 {TextWidgetCmd procedure, "index +displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "16.0 +1displaylines"
    list [.t index "11.5 +2d lines"] \
      [.t index "12.0 +2d lines"] [.t index "11.0 +2d lines"] \
      [.t index "13.0 +2d lines"] [.t index "13.0 +3d lines"] \
      [.t index "13.0 +4d lines"]
2855
2856
2857
2858
2859
2860
2861
2862

2863
2864
2865
2866
2867
2868
2869
2866
2867
2868
2869
2870
2871
2872

2873
2874
2875
2876
2877
2878
2879
2880







-
+







      [.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} {
test textDisp-19.17 {count -ypixels with indices in elided lines} {failsOnUbuntu failsOnXQuarz} {
    .t configure -wrap none
    .t delete 1.0 end
    for {set i 1} {$i < 100} {incr i} {
        .t insert end [string repeat "Line $i" 20]
        .t insert end "\n"
    }
    .t tag add hidden 5.15 20.15
2882
2883
2884
2885
2886
2887
2888
2889

2890
2891
2892
2893
2894
2895
2896
2893
2894
2895
2896
2897
2898
2899

2900
2901
2902
2903
2904
2905
2906
2907







-
+







      [.t count -ypixels 5.0 25.0] \
      [.t count -ypixels 25.0 5.0] \
      [.t count -ypixels 25.4 27.50] \
      [.t count -ypixels 35.0 38.0]
    .t yview 35.0
    lappend res [.t count -ypixels 5.0 25.0]
} [list [expr {4 * $fixedHeight}] [expr {3 * $fixedHeight}] 0 0 0 0 0 0 [expr {5 * $fixedHeight}] [expr {- 5 * $fixedHeight}] [expr {2 * $fixedHeight}] [expr {3 * $fixedHeight}] [expr {5 * $fixedHeight}]]
test textDisp-19.18 {count -ypixels with indices in elided lines} {
test textDisp-19.18 {count -ypixels with indices in elided lines} {failsOnUbuntu failsOnXQuarz} {
    .t configure -wrap none
    .t delete 1.0 end
    for {set i 1} {$i < 100} {incr i} {
        .t insert end [string repeat "Line $i" 20]
        .t insert end "\n"
    }
    .t tag add hidden 5.15 20.15
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
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







-
+




-
+




-
+




-
+





-
+







.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} {
test textDisp-20.1 {FindDLine} failsOnUbuntu {
    .t yview 48.0
    list [.t dlineinfo 46.0] [.t dlineinfo 47.0] [.t dlineinfo 49.0] \
	    [.t dlineinfo 58.0]
} [list {} {} [list 3 [expr {$fixedDiff + 16}] 49 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] {}]
test textDisp-20.2 {FindDLine} {
test textDisp-20.2 {FindDLine} failsOnUbuntu {
    .t yview 100.0
    .t yview -pickplace 53.0
    list [.t dlineinfo 50.0] [.t dlineinfo 50.14] [.t dlineinfo 50.21]
} [list [list 3 [expr {-1 - $fixedDiff/2}] 140 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {-1 - $fixedDiff/2}] 140 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {12 + $fixedDiff/2}] 133 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]]]
test textDisp-20.3 {FindDLine} {
test textDisp-20.3 {FindDLine} failsOnUbuntu {
    .t yview 100.0
    .t yview 49.0
    list [.t dlineinfo 50.0] [.t dlineinfo 50.24] [.t dlineinfo 57.0]
} [list [list 3 [expr {$fixedDiff + 16}] 140 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {2*$fixedDiff + 29}] 133 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] {}]
test textDisp-20.4 {FindDLine} {
test textDisp-20.4 {FindDLine} failsOnUbuntu {
    .t yview 100.0
    .t yview 42.0
    list [.t dlineinfo 50.0] [.t dlineinfo 50.24] [.t dlineinfo 50.40]
} [list [list 3 [expr {8*$fixedDiff + 107}] 140 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {9*$fixedDiff + 120}] 133 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] {}]
.t config -wrap none
test textDisp-20.5 {FindDLine} {
test textDisp-20.5 {FindDLine} failsOnUbuntu {
    .t yview 100.0
    .t yview 48.0
    list [.t dlineinfo 50.0] [.t dlineinfo 50.20] [.t dlineinfo 50.40]
} [list [list 3 [expr {3+2*$fixedHeight}] 371 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {3+2*$fixedHeight}] 371 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {3+2*$fixedHeight}] 371 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]]]

.t config -wrap word
test textDisp-21.1 {TkTextPixelIndex} {textfonts} {
2991
2992
2993
2994
2995
2996
2997
2998

2999
3000
3001
3002
3003
3004
3005
3002
3003
3004
3005
3006
3007
3008

3009
3010
3011
3012
3013
3014
3015
3016







-
+







.tt.u insert end $message
.tt.u mark set insert 3.10
tkwait visibility .tt.u
set res [.tt.u count -displaylines 3.10 2.173]
destroy .tt
unset message
set res
} {-1}
} -1

.t delete 1.0 end
.t insert end "Line 1"
for {set i 2} {$i <= 200} {incr i} {
    .t insert end "\nLine $i"
}
.t configure -wrap word
3399
3400
3401
3402
3403
3404
3405
3406

3407
3408
3409
3410
3411
3412
3413
3410
3411
3412
3413
3414
3415
3416

3417
3418
3419
3420
3421
3422
3423
3424







-
+







test textDisp-24.24 {TkTextCharLayoutProc, justification and tabs} {textfonts} {
    .t delete 1.0 end
    .t tag configure x -justify center
    .t insert 1.0 aa\tbb\tcc\tdd\t
    .t tag add x 1.0 end
    list [.t bbox 1.0] [.t bbox 1.10]
} [list [list 45 3 7 $fixedHeight] [list 94 3 7 $fixedHeight]]
test textDisp-24.25 {TkTextCharLayoutProc, justification and tabs} -constraints {textfonts} -setup {
test textDisp-24.25 {TkTextCharLayoutProc, justification and tabs} -constraints {textfonts failsOnXQuarz} -setup {
    text .tt -tabs {40 right} -wrap none -font $fixedFont
    pack .tt
} -body {
    .tt insert end \t9\n\t99\n\t999
    updateText
    list [.tt bbox 1.1] [.tt bbox 2.2] [.tt bbox 3.3]
} -cleanup {
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
3489
3490
3491
3492
3493
3494
3495

3496
3497
3498
3499
3500
3501
3502
3503
3504

3505
3506
3507
3508
3509
3510
3511
3512
3513

3514
3515
3516
3517
3518
3519
3520
3521
3522

3523
3524
3525
3526
3527
3528
3529
3530
3531

3532
3533
3534
3535
3536
3537
3538
3539
3540

3541
3542
3543
3544
3545
3546
3547
3548
3549
3550

3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563

3564
3565
3566
3567
3568
3569
3570
3571







-
+








-
+








-
+








-
+








-
+








-
+









-
+












-
+







    .t insert 1.0 a\t1.234
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    .t tag add y 1.5
    lindex [.t bbox 1.3] 0
} {120}
} 120
test textDisp-26.6 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t1,456.234
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    lindex [.t bbox 1.7] 0
} {120}
} 120
test textDisp-26.7 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t1.456.234,7
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    lindex [.t bbox 1.11] 0
} {120}
} 120
test textDisp-26.8 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\ttest
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    lindex [.t bbox 1.6] 0
} {120}
} 120
test textDisp-26.9 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t1234
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    lindex [.t bbox 1.6] 0
} {120}
} 120
test textDisp-26.10 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t1.234567
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.5
    lindex [.t bbox 1.3] 0
} {120}
} 120
test textDisp-26.11 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\tx=1.234567
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.7
    .t tag add y 1.9
    lindex [.t bbox 1.5] 0
} {120}
} 120
test textDisp-26.12 {AdjustForTab procedure, adjusting chunks} {
    .t delete 1.0 end
    .t insert 1.0 a\tx1.234567
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.7
    .t tag add y 1.9
    button .b -text "="
    .t window create 1.3 -window .b
    updateText
    lindex [.t bbox 1.5] 0
} {120}
} 120
test textDisp-26.13 {AdjustForTab procedure, not enough space} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 "abc\txyz\tqrs\txyz\t0"
    .t tag delete x
    .t tag configure x -tabs {10 30 center 50 right 120}
    .t tag add x 1.0 end
    list [lindex [.t bbox 1.4] 0] [lindex [.t bbox 1.8] 0] \
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
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







-
+















-
+















-
+







    updateText
    set res [.t bbox 1.20]
    # Now, Tk's interpolated tabs should be the same as
    # non-interpolated.
    .t configure -tabs $precisetab
    updateText
    expr {[lindex $res 0] - [lindex [.t bbox 1.20] 0]}
} {0}
} 0

.t configure -wrap char -tabs {} -width 20
updateText
test textDisp-27.8 {SizeOfTab procedure, right alignment} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\t\txyzzyabc
    .t tag delete x
    .t tag configure x -tabs {100 left 140 right}
    .t tag add x 1.0 end
    list [.t bbox 1.6] [.t bbox 1.7]
} [list [list 137 5 7 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-27.9 {SizeOfTab procedure, left alignment} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\txyzzyabc
    .t tag delete x
    .t tag configure x -tabs {120}
    .t tag configure x -tabs 120
    .t tag add x 1.0 end
    list [.t bbox 1.3] [.t bbox 1.4]
} [list [list 131 5 13 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-27.10 {SizeOfTab procedure, numeric alignment} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\t123.4
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    list [.t bbox 1.3] [.t bbox 1.4]
} [list [list 117 5 27 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-27.11 {SizeOfTab procedure, making tabs at least as wide as a space} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 abc\tdefghijklmnopqrst
    .t tag delete x
    .t tag configure x -tabs {120}
    .t tag configure x -tabs 120
    .t tag add x 1.0 end
    list [.t bbox 1.5] [.t bbox 1.6]
} [list [list 131 5 13 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]

proc bizarre_scroll args {
    .t2.t delete 5.0 end
}
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
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







-
+






-
+





-
+












-
+
















-
+













-
+




-
+

















-
+
















-
+












-
+




-
+
















-
+



-
+







} [list [list [expr {16.0/30}] 1.0] 300x50+-155+[expr {$fixedDiff + 18}] {}]
test textDisp-30.1 {elidden text joining multiple logical lines} {
    .t2.t delete 1.0 end
    .t2.t insert 1.0 "1111\n2222\n3333"
    .t2.t tag configure elidden -elide 1 -background red
    .t2.t tag add elidden 1.2 3.2
    .t2.t count -displaylines 1.0 end
} {1}
} 1
test textDisp-30.2 {elidden text joining multiple logical lines} {
    .t2.t delete 1.0 end
    .t2.t insert 1.0 "1111\n2222\n3333"
    .t2.t tag configure elidden -elide 1 -background red
    .t2.t tag add elidden 1.2 2.2
    .t2.t count -displaylines 1.0 end
} {2}
} 2
catch {destroy .t2}

.t configure -height 1
updateText

test textDisp-31.1 {line embedded window height update} {
test textDisp-31.1 {line embedded window height update} failsOnUbuntu {
    set res {}
    .t delete 1.0 end
    .t insert end "abcd\nefgh\nijkl\nmnop\nqrst\nuvwx\nyx"
    frame .t.f -background red -width 100 -height 100
    .t window create 3.0 -window .t.f
    lappend res [.t count -update -ypixels 1.0 end]
    .t.f configure -height 10
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
    set res
} [list [expr {100 + $fixedHeight * 6}] [expr {100 + $fixedHeight * 6}] [expr {$fixedHeight * 7}]]

test textDisp-31.2 {line update index shifting} {
test textDisp-31.2 {line update index shifting} failsOnUbuntu {
    set res {}
    .t.f configure -height 100
    updateText
    lappend res [.t count -update -ypixels 1.0 end]
    .t.f configure -height 10
    .t insert 1.0 "abc\n"
    .t insert 1.0 "abc\n"
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
    .t.f configure -height 100
    .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} {
test textDisp-31.3 {line update index shifting} failsOnUbuntu {
    # Should do exactly the same as the above, as long
    # as we are correctly tagging the correct lines for
    # recalculation.  The 'update' and 'delay' must be
    # long enough to ensure all asynchronous updates
    # have been performed.
    set res {}
    .t.f configure -height 100
    updateText
    lappend res [.t count -update -ypixels 1.0 end]
    .t.f configure -height 10
    .t insert 1.0 "abc\n"
    .t insert 1.0 "abc\n"
    lappend res [.t count -ypixels 1.0 end]
    update ; after 1000 ; update
    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]
    update ; after 1000 ; update
    delay
    lappend res [.t count -ypixels 1.0 end]
    set res
} [list [expr {100 + $fixedHeight * 6}] [expr {100 + $fixedHeight * 8}] [expr {$fixedHeight * 9}] [expr {$fixedHeight * 7}] [expr {100 + $fixedHeight * 6}]]

test textDisp-31.4 {line embedded image height update} {
    set res {}
    image create photo textest -height 100 -width 10
    .t delete 3.0
    .t image create 3.0 -image textest
    updateText
    lappend res [.t count -update -ypixels 1.0 end]
    textest configure -height 10
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
    set res
} [list [expr {100 + $fixedHeight * 6}] [expr {100 + $fixedHeight * 6}] [expr {$fixedHeight * 7}]]

test textDisp-31.5 {line update index shifting} {
test textDisp-31.5 {line update index shifting} failsOnUbuntu {
    set res {}
    textest configure -height 100
    updateText
    lappend res [.t count -update -ypixels 1.0 end]
    textest configure -height 10
    .t insert 1.0 "abc\n"
    .t insert 1.0 "abc\n"
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
    textest configure -height 100
    .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.6 {line update index shifting} {
test textDisp-31.6 {line update index shifting} failsOnUbuntu {
    # 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]
    update ; after 1000 ; update
    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]
    update ; after 1000 ; update
    delay
    lappend res [.t count -ypixels 1.0 end]
    set res
} [list [expr {100 + $fixedHeight * 6}] [expr {100 + $fixedHeight * 8}] [expr {$fixedHeight * 9}] [expr {$fixedHeight * 7}] [expr {100 + $fixedHeight * 6}]]

test textDisp-31.7 {line update index shifting, elided} {
    # The 'update' and 'delay' must be long enough to ensure all
    # asynchronous updates have been performed.
    set res {}
    .t delete 1.0 end
    lappend res [.t count -update -ypixels 1.0 end]
    .t insert 1.0 "abc\nabc"
    .t insert 1.0 "abc\n"
    lappend res [.t count -update -ypixels 1.0 end]
    .t tag configure elide -elide 1
    .t tag add elide 1.3 2.1
    lappend res [.t count -ypixels 1.0 end]
    update ; after 1000 ; update
    delay
    lappend res [.t count -ypixels 1.0 end]
    .t delete 1.0 3.0
    lappend res [.t count -ypixels 1.0 end]
    update ; after 1000 ; update
    delay
    lappend res [.t count -ypixels 1.0 end]
    set res
} [list [expr {$fixedHeight * 1}] [expr {$fixedHeight * 3}] [expr {$fixedHeight * 3}] [expr {$fixedHeight * 2}] [expr {$fixedHeight * 1}] [expr {$fixedHeight * 1}]]

test textDisp-32.0 {everything elided} {
    # Must not crash
    pack [text .tt]
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
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







+








+













+

+

+
-
+
-

-
+












-
+







} -cleanup {
    image delete $img
    destroy .tt
}

test textDisp-33.0 {one line longer than fits in the widget} {
    pack [text .tt -wrap char]
    updateText
    .tt insert 1.0 [string repeat "more wrap + " 300]
    updateText
    .tt see 1.0
    lindex [.tt yview] 0
} {0.0}
test textDisp-33.1 {one line longer than fits in the widget} {
    destroy .tt
    pack [text .tt -wrap char]
    updateText
    .tt insert 1.0 [string repeat "more wrap + " 300]
    updateText
    .tt yview "1.0 +1 displaylines"
    if {[lindex [.tt yview] 0] > 0.1} {
	set result "window should be scrolled to the top"
    } else {
	set result "ok"
    }
} {ok}
test textDisp-33.2 {one line longer than fits in the widget} {
    destroy .tt
    pack [text .tt -wrap char]
    .tt debug 1
    updateText
    set tk_textHeightCalc ""
    set timer [after 200 lappend tk_textHeightCalc "Timed out"]
    .tt insert 1.0 [string repeat "more wrap + " 1]
    vwait tk_textHeightCalc
    after 100 ; update idletasks
    after cancel $timer
    # Nothing should have been recalculated.
    set tk_textHeightCalc
} {}
} {1.0}
test textDisp-33.3 {one line longer than fits in the widget} {
    destroy .tt
    pack [text .tt -wrap char]
    .tt debug 1
    set tk_textHeightCalc ""
    .tt insert 1.0 [string repeat "more wrap + " 300]
    updateText
    .tt count -update -ypixels 1.0 end
    updateText
    # Each line should have been recalculated just once
    .tt debug 0
    expr {[llength $tk_textHeightCalc] == [.tt count -displaylines 1.0 end]}
} {1}
} 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

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 (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit

Changes to tests/textIndex.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



-
-
-
+
+
+


-
+







# This file is a Tcl script to test the code in the file tkTextIndex.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.1
package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

catch {destroy .t}
text .t -font {Courier -12} -width 20 -height 10
pack .t -expand 1 -fill both
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
b\u4e4fy GIrl .#@? x_yz
by GIrl .#@? x_yz
!@#$%
Line 7"

image create photo textimage -width 10 -height 10
textimage put red -to 0 0 9 9

test textIndex-1.1 {TkTextMakeByteIndex} {testtext} {
114
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 \xb9 (the 2nd byte of UTF rep of 0x4e4f).
    # Wrong answer would be ¹ (the 2nd byte of UTF rep of 0x4e4f).

    set x [testtext .t byteindex 5 2]
    list $x [.t get insert]
} {{5.2 4} y}
test textIndex-1.18 {TkTextMakeByteIndex: prevent splitting UTF-8 character} \
	{testtext} {
    # ((byteIndex > index) && (segPtr->typePtr == &tkTextCharType))
    testtext .t byteindex 5 1
    .t get insert
} "\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 \xb9 (the 2nd byte of UTF rep of 0x4e4f).
    # Wrong answer would be ¹ (the 2nd byte of UTF rep of 0x4e4f).

    .t mark set insert 5.2
    .t get insert
} y
test textIndex-2.13 {TkTextMakeCharIndex: verify index is in range} {
    # not (segPtr->typePtr == &tkTextCharType)

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"]
}
805
806
807
808
809
810
811
812

813
814
815

816
817
818
819
820
821
822
805
806
807
808
809
810
811

812
813
814

815
816
817
818
819
820
821
822







-
+


-
+








test textIndex-19.12.1 {Display lines} {
    .t index "2.50 - 100 displaylines"
} {1.0}

test textIndex-19.12.2 {Display lines} {
    .t compare [.t index "2.50 + 100 displaylines"] == "end - 1 c"
} {1}
} 1

test textIndex-19.13 {Display lines} {
    destroy {*}[pack slaves .]
    destroy {*}[pack content .]
    text .txt -height 1 -wrap word -yscroll ".sbar set" -width 400
    scrollbar .sbar -command ".txt yview"
    grid .txt .sbar -sticky news
    grid configure .sbar -sticky ns
    grid rowconfigure    . 0 -weight 1
    grid columnconfigure . 0 -weight 1
    .txt configure -width 10
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
867
868
869
870
871
872
873

874
875
876

877
878
879

880
881
882

883
884
885

886
887
888
889
890
891
892
893







-
+


-
+


-
+


-
+


-
+







test textIndex-21.8 {text index wordend} {
    text_test_word worde "x.y" 0
} 1
test textIndex-21.9 {text index wordend} {
    text_test_word worde "x.y" end-1
} 2
test textIndex-21.10 {text index wordend, unicode} {
    text_test_word wordend "xyz\u00c7de fg" 0
    text_test_word wordend "xyzÇde fg" 0
} 6
test textIndex-21.11 {text index wordend, unicode} {
    text_test_word wordend "xyz\uc700de fg" 0
    text_test_word wordend "xyzde fg" 0
} 6
test textIndex-21.12 {text index wordend, unicode} {
    text_test_word wordend "xyz\u203fde fg" 0
    text_test_word wordend "xyzde fg" 0
} 6
test textIndex-21.13 {text index wordend, unicode} {
    text_test_word wordend "xyz\u2045de fg" 0
    text_test_word wordend "xyzde fg" 0
} 3
test textIndex-21.14 {text index wordend, unicode} {
    text_test_word wordend "\uc700\uc700 abc" 8
    text_test_word wordend "윀윀 abc" 8
} 6

test textIndex-22.5 {text index wordstart} {
    text_test_word wordstart "one two three_words" 400
} 8
test textIndex-22.6 {text index wordstart} {
    text_test_word wordstart "one two three_words" 2
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
901
902
903
904
905
906
907

908
909
910

911
912
913

914
915
916
917
918


919
920
921
922
923
924
925
926
927







-
+


-
+


-
+




-
-
+
+







test textIndex-22.9 {text index wordstart} {
    text_test_word wordstart "one two three" 4
} 4
test textIndex-22.10 {text index wordstart} {
    text_test_word wordstart "one two three" end-5
} 7
test textIndex-22.11 {text index wordstart, unicode} {
    text_test_word wordstart "one tw\u00c7o three" 7
    text_test_word wordstart "one twÇo three" 7
} 4
test textIndex-22.12 {text index wordstart, unicode} {
    text_test_word wordstart "ab\uc700\uc700 cdef ghi" 12
    text_test_word wordstart "ab윀윀 cdef ghi" 12
} 10
test textIndex-22.13 {text index wordstart, unicode} {
    text_test_word wordstart "\uc700\uc700 abc" 8
    text_test_word wordstart "윀윀 abc" 8
} 3
test textIndex-22.14 {text index wordstart, unicode, start index at internal segment start} {
    catch {destroy .t}
    text .t
    .t insert end "C'est du texte en fran\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 insert end "C'est du texte en français\n"
    .t insert end "Это текст на русском"
    .t mark set insert 1.23
    set res [.t index "1.23 wordstart"]
    .t mark set insert 2.16
    lappend res [.t index "2.16 wordstart"] [.t index "2.15 wordstart"]
} {1.18 2.13 2.13}
test textIndex-22.15 {text index display wordstart} {
    catch {destroy .t}

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 (c) 1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

48
49
50
51
52
53
54
55

56
57
58
59
60
61
62
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62







-
+







test textMark-1.4 {TkTextMarkCmd - "gravity" option} -body {
    .t mark set x 1.3
    .t insert 1.3 x
    list [.t mark gravity x] [.t index x]
} -result {right 1.4}
test textMark-1.5 {TkTextMarkCmd - "gravity" option} -body {
    .t mark set x 1.3
    .t mark g x left
    .t mark gr x left
    .t insert 1.3 x
    list [.t mark gravity x] [.t index x]
} -result {left 1.3}
test textMark-1.6 {TkTextMarkCmd - "gravity" option} -body {
    .t mark set x 1.3
    .t mark gravity x right
    .t insert 1.3 x
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







-
+







} -cleanup {
  .t configure -startline {} -endline {}
  .pt configure -startline {} -endline {}
  .t mark unset mymark
} -result {1 {bad text index "mymark"} 1.0 1.0 1 {bad text index "mymark"} L 1 {bad text index "mymark"}}
test textMark-6.5 {insert and current marks in an empty peer - bug 3487407} -body {
  .t mark set insert 1.0
  .t configure -start 5 -end 5
  .t configure -startline 5 -endline 5
  set res [.t index insert]
} -cleanup {
  .t configure -startline {} -endline {}
} -result {1.0}

test textMark-7.1 {MarkFindNext - invalid mark name} -body {
    .t mark next bogus

Changes to tests/textTag.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 tkTextTag.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 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
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38







+
+
+







testConstraint haveFontSizes [expr {
    [font metrics $textWidgetFont -fixed] &&
    [font actual  $textWidgetFont -size] == 12 &&
    [font metrics $bigFont -fixed] &&
    [font actual  $bigFont -size] == 24 }
]

testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint failsOnUbuntuNoXft [expr {[testConstraint failsOnUbuntu] || (![catch {tk::pkgconfig get fontsystem} fs] && ($fs eq "xft"))}]

destroy .t
text .t -width 20 -height 10

pack .t -expand 1 -fill both
update
.t debug on

484
485
486
487
488
489
490
491

492
493
494
495
496
497
498
487
488
489
490
491
492
493

494
495
496
497
498
499
500
501







-
+







} -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? ?-option value ...?"}
} -returnCodes error -result {wrong # args: should be ".t tag configure tagName ?-option value ...?"}
test textTag-5.2 {TkTextTagCmd - "configure" option} -body {
    .t tag configure x -foo
} -returnCodes error -result {unknown option "-foo"}
test textTag-5.3 {TkTextTagCmd - "configure" option} -body {
    .t tag configure x -background red -underline
} -cleanup {
    .t tag delete x
1338
1339
1340
1341
1342
1343
1344
1345

1346
1347
1348
1349
1350
1351
1352
1341
1342
1343
1344
1345
1346
1347

1348
1349
1350
1351
1352
1353
1354
1355







-
+







    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
    haveFontSizes failsOnUbuntuNoXft
} -setup {
    .t tag delete {*}[.t tag names]
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50
    .t configure -font $textWidgetFont -wrap none
} -body {
    .t tag configure big -font $bigFont
1434
1435
1436
1437
1438
1439
1440
1441

1442
1443
1444
1445
1446
1447
1448
1437
1438
1439
1440
1441
1442
1443

1444
1445
1446
1447
1448
1449
1450
1451







-
+







    .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
    haveFontSizes failsOnUbuntuNoXft
} -setup {
    foreach i {big a b c d} {
        .t tag remove $i 1.0 end
    }
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50
    .t configure -font $textWidgetFont -wrap none
1456
1457
1458
1459
1460
1461
1462
1463

1464
1465
1466
1467
1468
1469
1470
1459
1460
1461
1462
1463
1464
1465

1466
1467
1468
1469
1470
1471
1472
1473







-
+







    .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
    haveFontSizes failsOnUbuntuNoXft
} -setup {
    foreach i {big a b c d} {
        .t tag remove $i 1.0 end
    }
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50
    .t configure -font $textWidgetFont -wrap none
1518
1519
1520
1521
1522
1523
1524
1525

1526
1527
1528
1529
1530
1531
1532
1533
1534
1521
1522
1523
1524
1525
1526
1527

1528
1529
1530
1531
1532
1533
1534
1535
1536
1537







-
+









    # the actual tagged characters themselves.
    event gen .t <Motion> -warp 1 -x 0 -y 0 ; update
    event gen .t <Motion> -warp 1 -x 10 -y 10 ; update
    event gen .t <Motion> -warp 1 -x 25 -y 25 ; update
    event gen .t <Motion> -warp 1 -x 20 -y 20 ; update
    event gen .t <Motion> -warp 1 -x 10 -y 10 ; update
    event gen .t <Motion> -warp 1 -x 25 -y 25 ; update
    return $res
    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
1
2
3



4
5
6
7
8
9
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
25



-
-
-
+
+
+







+
+


-
+







# This file is a Tcl script to test the code in the file tkTextWind.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 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(CI)] || ![string match Linux $::tcl_platform(os)]}]

deleteWindows

set fixedFont {"Courier New" -12}
set fixedFont {"Courier" -12}
set fixedHeight [font metrics $fixedFont -linespace]
set fixedWidth [font measure $fixedFont m]
set fixedAscent [font metrics $fixedFont -ascent]

# Widget used in almost all tests
set tWidth 30
set tHeight 6
578
579
580
581
582
583
584
585

586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602

603
604
605
606
607
608
609
580
581
582
583
584
585
586

587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603

604
605
606
607
608
609
610
611







-
+
















-
+







} -result [list \
    [list [expr {$padx+2*$fixedWidth}] $pady 10 20] \
    [list [expr {$padx+2*$fixedWidth+10}] [expr {$pady+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight] \
    [list [expr {$padx+2*$fixedWidth}] $pady 25 30] \
    [list [expr {$padx+2*$fixedWidth+25}] [expr {$pady+((30-$fixedHeight)/2)}] $fixedWidth $fixedHeight]]


test textWind-7.1 {EmbWinLostSlaveProc procedure} -setup {
test textWind-7.1 {EmbWinLostContentProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    update
    place .f -in .t -x 100 -y 50
    update
    list [winfo geom .f] [.t bbox 1.2]
} -cleanup {
    destroy .f
} -result [list \
    10x20+[expr {$padx+100}]+[expr {$pady+50}] \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]]

test textWind-7.2 {EmbWinLostSlaveProc procedure} -setup {
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
747
748
749
750
751
752
753

754


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
749
750
751
752
753
754
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







+
-
+
+



+




-











-
+


















-
+







    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
	    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
    }
    set msg {}
    update idletasks
    lappend msg [winfo exists .t.f.f]
} -cleanup {
    destroy .t.f
    rename bgerror {}
} -result {{{can't embed .t.f.f relative to .t}} 1}

test textWind-10.6 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    proc bgerror args {
        global msg
        if {[lsearch -exact $msg $args] == -1} {
        if {[lsearch -exact $msg $args] < 0} {
            lappend msg $args
        }
    }
} -body {
    .t insert 1.0 "Some sample text"
    update
    .t window create 1.5 -create {
        concat .t
    }
    set msg {}
    update
    lappend msg [.t bbox 1.5]
} -cleanup {
    rename bgerror {}
} -result [list \
    {{can't embed .t relative to .t}} \
    [list [expr {$padx+5*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]]

test textWind-10.7 {EmbWinLayoutProc procedure, error in creating window} -setup {
test textWind-10.7 {EmbWinLayoutProc procedure, error in creating window} -constraints failsOnUbuntu -setup {
    .t delete 1.0 end
    destroy .t2
    proc bgerror args {
        global msg
	lappend msg $args
    }
} -body {
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
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







-
+














-
+















-
+






-
-
+
+







-
+















-
+








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 125 -height 20 -bg $color -bd 2 -relief raised
    frame .f -width [expr {($tWidth-12)*$fixedWidth-1}] -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list [expr {$padx+12*$fixedWidth}] $pady [expr {$tWidth*$fixedWidth-12*$fixedWidth}] 20] \
    [list $padx [expr {$pady+20}] $fixedWidth $fixedHeight]]

test textWind-10.11 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap char
    .t insert 1.0 "Some sample text"
    frame .f -width 126 -height 20 -bg $color -bd 2 -relief raised
    frame .f -width [expr {($tWidth-12)*$fixedWidth}] -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list [expr {$padx+12*$fixedWidth}] $pady [expr {$tWidth*$fixedWidth-12*$fixedWidth}] 20] \
    [list $padx [expr {$pady+20}] $fixedWidth $fixedHeight]]

test textWind-10.12 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap char
    .t insert 1.0 "Some sample text"
    frame .f -width 127 -height 20 -bg $color -bd 2 -relief raised
    frame .f -width [expr {($tWidth-12)*$fixedWidth+1}] -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list $padx [expr {$pady+$fixedHeight}] 127 20] \
    [list [expr {$padx+127}] [expr {$pady+$fixedHeight+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight]]
    [list $padx [expr {$pady+$fixedHeight}] [expr {($tWidth-12)*$fixedWidth+1}] 20] \
    [list [expr {$padx+($tWidth-12)*$fixedWidth+1}] [expr {$pady+$fixedHeight+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight]]

test textWind-10.13 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap none
    .t insert 1.0 "Some sample text"
    frame .f -width 130 -height 20 -bg $color -bd 2 -relief raised
    frame .f -width [expr {($tWidth-12)*$fixedWidth+5}] -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list [expr {$padx+12*$fixedWidth}] $pady [expr {$tWidth*$fixedWidth-12*$fixedWidth}] 20] \
    {}]

test textWind-10.14 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap none
    .t insert 1.0 "Some sample text"
    frame .f -width 130 -height 220 -bg $color -bd 2 -relief raised
    frame .f -width [expr {($tWidth-12)*$fixedWidth+5}] -height 220 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list [expr {$padx+12*$fixedWidth}] $pady [expr {$tWidth*$fixedWidth-12*$fixedWidth}] [expr {$tHeight*$fixedHeight}]] \

Changes to tests/tk.test.

1
2
3
4
5
6



7
8
9
10
11
12
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
1
2
3



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 the tk command.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright (c) 2002 ActiveState Corporation.
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# Copyright © 2002 ActiveState Corporation.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

testConstraint testprintf [llength [info command testprintf]]

test tk-1.1 {tk command: general} -body {
    tk
} -returnCodes error -result {wrong # args: should be "tk subcommand ?arg ...?"}
test tk-1.2 {tk command: general} -body {
    tk xyz
} -returnCodes error -result {unknown or ambiguous subcommand "xyz": must be appname, busy, caret, fontchooser, inactive, scaling, useinputmethods, or windowingsystem}
} -returnCodes error -result {unknown or ambiguous subcommand "xyz": must be appname, busy, caret, fontchooser, inactive, scaling, sysnotify, systray, useinputmethods, or windowingsystem}

# Value stored to restore default settings after 2.* tests
set appname [tk appname]
test tk-2.1 {tk command: appname} -body {
    tk appname xyz abc
} -returnCodes error -result {wrong # args: should be "tk appname ?newName?"}
test tk-2.2 {tk command: appname} -body {
155
156
157
158
159
160
161
162

163
164
165
166
167
168
169
155
156
157
158
159
160
161

162
163
164
165
166
167
168
169







-
+







    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 == -1 || ( $i > 90 && $i < 200 )}
    expr {$i < 0 || ( $i > 90 && $i < 200 )}
} -result 1

test tk-7.1 {tk inactive in a safe interpreter} -body {
# tk inactive in safe interpreters
    safe::interpCreate foo
    safe::loadTk foo
    foo eval {tk inactive}

Changes to tests/ttk/all.tcl.

1
2
3
4
5
6
7

8
9
10
11
12

13
14
15
16
17
18


19

20
1
2
3
4
5
6

7
8
9
10
11

12
13
14
15
16
17
18
19
20

21







-
+




-
+






+
+
-
+
-
# all.tcl --
#
# This file contains a top-level script to run all of the ttk
# tests.  Execute it by invoking "source all.tcl" when running tktest
# in this directory.
#
# Copyright (c) 2007 by the Tk developers.
# Copyright © 2007 the Tk developers.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

package require Tk ;# This is the Tk test suite; fail early if no Tk!
package require tk ;# This is the Tk test suite; fail early if no Tk!
package require tcltest 2.2
tcltest::configure {*}$argv
tcltest::configure -testdir [file normalize [file dirname [info script]]]
tcltest::configure -loadfile \
    [file join [file dirname [tcltest::testsDirectory]] constraints.tcl]
tcltest::configure -singleproc 1
set ErrorOnFailures [info exists env(ERROR_ON_FAILURES)]
encoding system utf-8
tcltest::runAllTests
if {[tcltest::runAllTests] && $ErrorOnFailures} {exit 1}

Changes to tests/ttk/checkbutton.test.

1
2
3
4
5
6



7
8
9
10
11
12
13
1
2
3
4


5
6
7
8
9
10
11
12
13
14




-
-
+
+
+







#
# ttk::checkbutton widget tests.
#

package require Tk
package require tcltest ; namespace import -force tcltest::*
package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test checkbutton-1.1 "Checkbutton check" -body {
    pack [ttk::checkbutton .cb -text "TCheckbutton" -variable cb]
}
test checkbutton-1.2 "Checkbutton invoke" -body {
    .cb invoke
66
67
68
69
70
71
72














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







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

    # shall simply not crash
    ttk::checkbutton .cbev -variable {}
    .cbev invoke
} -cleanup {
    destroy .cbev
} -result {}

test checkbutton-2.1 "style command" -body {
    ttk::checkbutton .w
    list [.w cget -style] [.w style] [winfo class .w]
} -cleanup {
    destroy .w
} -result {{} TCheckbutton TCheckbutton}
test checkbutton-2.2 "style command" -body {
    ttk::style configure customStyle.TCheckbutton
    ttk::checkbutton .w -style customStyle.TCheckbutton
    list [.w cget -style] [.w style] [winfo class .w]
} -cleanup {
    destroy .w
} -result {customStyle.TCheckbutton customStyle.TCheckbutton TCheckbutton}

tcltest::cleanupTests

Changes to tests/ttk/combobox.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




-
-
+
+
+








-
+







#
# ttk::combobox widget tests
#

package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*
package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test combobox-1.0 "Combobox tests -- setup" -body {
    ttk::combobox .cb
} -result .cb

test combobox-1.1 "Bad -values list" -body {
    .cb configure -values "bad \{list"
} -result "unmatched open brace in list" -returnCodes 1
} -result "unmatched open brace in list" -returnCodes error

test combobox-1.end "Combobox tests -- cleanup" -body {
    destroy .cb
}

test combobox-2.0 "current command" -body {
    ttk::combobox .cb -values [list a b c d e a]
81
82
83
84
85
86
87














88
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103







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

    lappend result Select [winfo ismapped .cb.popdown] [.cb get]
    update
    set result
} -result [list Start 0 {} Post 1 {} Select 0 b Event 0 b] -cleanup {
    destroy .cb
}

test combobox-4.1 "style command" -body {
    ttk::combobox .w
    list [.w cget -style] [.w style] [winfo class .w]
} -cleanup {
    destroy .w
} -result {{} TCombobox TCombobox}
test combobox-4.2 "style command" -body {
    ttk::style configure customStyle.TCombobox
    ttk::combobox .w -style customStyle.TCombobox
    list [.w cget -style] [.w style] [winfo class .w]
} -cleanup {
    destroy .w
} -result {customStyle.TCombobox customStyle.TCombobox TCombobox}

tcltest::cleanupTests

Changes to tests/ttk/entry.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
15
16
17




-
-
+
+
+

+
+







#
# Tile package: entry widget tests
#

package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*
package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]

variable scrollInfo
proc scroll args {
    global scrollInfo
    set scrollInfo $args
}

70
71
72
73
74
75
76
77

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

80
81
82
83
84
85
86
87







-
+







test entry-2.1 "Create entry before scrollbar" -body {
    pack [ttk::entry .te -xscrollcommand [list .tsb set]] \
	-expand true -fill both
    pack [ttk::scrollbar .tsb -orient horizontal -command [list .te xview]] \
    	-expand false -fill x
}  -cleanup {destroy .te .tsb}

test entry-2.1.1 "Create entry before scrollbar - scrollbar catches up" -body {
test entry-2.1.1 "Create entry before scrollbar - scrollbar catches up" -constraints failsOnUbuntu -body {
    pack [ttk::entry .te -xscrollcommand [list .tsb set]] \
	-expand true -fill both
    .te insert end [string repeat "abc" 50]
    catch {update} ; # error triggers because the -xscrollcommand callback
                     # errors out: invalid command name ".tsb"
    pack [ttk::scrollbar .tsb -orient horizontal -command [list .te xview]] \
    	-expand false -fill x
102
103
104
105
106
107
108
109

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

112
113
114
115
116
117
118
119







-
+







# 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 \u4e4e]
    variable ux [font measure $fixed ]

    pack [ttk::entry .e -font $fixed -width 20]
    update
}

test entry-3.1 "bbox widget command" -body {
    .e delete 0 end
337
338
339
340
341
342
343












344
345
346
347
348
349
350
351
352
353
354
355
356














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







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













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

    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-12.1 "style command" -body {
    ttk::entry .w
    list [.w cget -style] [.w style] [winfo class .w]
} -cleanup {
    destroy .w
} -result {{} TEntry TEntry}
test entry-12.2 "style command" -body {
    ttk::style configure customStyle.TEntry
    ttk::entry .w -style customStyle.TEntry
    list [.w cget -style] [.w style] [winfo class .w]
} -cleanup {
    destroy .w
} -result {customStyle.TEntry customStyle.TEntry TEntry}

tcltest::cleanupTests

Changes to tests/ttk/image.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
22
-
-
+
+
+











-
+







package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*
package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test image-1.1 "Bad image element" -body {
    ttk::style element create BadImage image badimage
} -returnCodes error -result {image "badimage" doesn't exist}

test image-1.2 "Duplicate element" -setup {
    image create photo test.element -width 10 -height 10
    ttk::style element create testElement image test.element
} -body {
    ttk::style element create testElement image test.element
} -returnCodes 1 -result "Duplicate element testElement"
} -returnCodes error -result "Duplicate element testElement"

test image-2.0 "Deletion of displayed image (label)" -setup {
     image create photo test.image -width 10 -height 10
} -body {
    pack [set w [ttk::label .ttk_image20 -image test.image]]
    tkwait visibility $w
    image delete test.image

Changes to tests/ttk/labelframe.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


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

14
15
16
17
18
19

20
21
22
23
24

25
26
27
28

29
30
31
32
33
34

35
36
37
38
39
40

41
42
43
44
45

46
47
48
49
50

51
52
53
54
55

56
57
58
59
60

61
62
63
64
65
66

67
68
69
70
71
72
73
74
75
76

77
78
79
80
81
82
83
84

85
86
87
88
89
90

91
92
93
94
95

96
97
98
99
100
101
102

103
104
105
106
107
108
109

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










-
+





-
+




-
+



-
+





-
+





-
+




-
+




-
+




-
+




-
+





-
+









-
+







-
+





-
+




-
+






-
+






-
+




















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

package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*
package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test labelframe-1.0 "Setup" -body {
    pack [ttk::labelframe .lf] -expand true -fill both
}

test labelframe-2.1 "Can't use indirect descendant as labelwidget" -body {
    ttk::frame .lf.t
    ttk::checkbutton .lf.t.cb
    .lf configure -labelwidget .lf.t.cb
} -returnCodes 1 -result "can't *" -match glob \
} -returnCodes error -result "can't *" -match glob \
  -cleanup { destroy .lf.t } ;

test labelframe-2.2 "Can't use toplevel as labelwidget" -body {
    toplevel .lf.t
    .lf configure -labelwidget .lf.t
} -returnCodes 1 -result "can't *" -match glob \
} -returnCodes error -result "can't *" -match glob \
  -cleanup { destroy .lf.t } ;

test labelframe-2.3 "Can't use non-windows as -labelwidget" -body {
    .lf configure -labelwidget BogusWindowName
} -returnCodes 1 -result {bad window path name "BogusWindowName"}
} -returnCodes error -result {bad window path name "BogusWindowName"}

test labelframe-2.4 "Can't use nonexistent-windows as -labelwidget" -body {
    .lf configure -labelwidget .nosuchwindow
} -returnCodes 1 -result {bad window path name ".nosuchwindow"}
} -returnCodes error -result {bad window path name ".nosuchwindow"}


###
# See also series labelframe-4.x
#
test labelframe-3.1 "Add child slave" -body {
test labelframe-3.1 "Add child content" -body {
    checkbutton .lf.cb -text "abcde"
    .lf configure -labelwidget .lf.cb
    list [update; winfo viewable .lf.cb] [winfo manager .lf.cb]
} -result [list 1 labelframe]

test labelframe-3.2 "Remove child slave" -body {
test labelframe-3.2 "Remove child content" -body {
    .lf configure -labelwidget {}
    list [update; winfo viewable .lf.cb] [winfo manager .lf.cb]
} -result [list 0 {}]

test labelframe-3.3 "Re-add child slave" -body {
test labelframe-3.3 "Re-add child content" -body {
    .lf configure -labelwidget .lf.cb
    list [update; winfo viewable .lf.cb] [winfo manager .lf.cb]
} -result [list 1 labelframe]

test labelframe-3.4 "Re-manage child slave" -body {
test labelframe-3.4 "Re-manage child content" -body {
    pack .lf.cb -side right
    list [update; winfo viewable .lf.cb] [winfo manager .lf.cb] [.lf cget -labelwidget]
} -result [list 1 pack {}]

test labelframe-3.5 "Re-add child slave" -body {
test labelframe-3.5 "Re-add child content" -body {
    .lf configure -labelwidget .lf.cb
    list [update; winfo viewable .lf.cb] [winfo manager .lf.cb]
} -result [list 1 labelframe]

test labelframe-3.6 "Destroy child slave" -body {
test labelframe-3.6 "Destroy child content" -body {
    destroy .lf.cb
    .lf cget -labelwidget
} -result {}

###
# Re-run series labelframe-3.x with nonchild slaves.
# Re-run series labelframe-3.x with nonchild content.
#
# @@@ ODDITY, 14 Nov 2005:
# @@@ labelframe-4.1 fails if .cb is a [checkbutton],
# @@@ but seems to succeed if it's some other widget class.
# @@@ I suspect a race condition; unable to track it down ATM.
#
# @@@ FOLLOWUP: This *may* have been caused by a bug in ManagerIdleProc
# @@@ (see manager.c r1.11). There's still probably a race condition in here.
#
test labelframe-4.1 "Add nonchild slave" -body {
test labelframe-4.1 "Add nonchild content" -body {
    checkbutton .cb -text "abcde"
    .lf configure -labelwidget .cb
    update
    list [winfo ismapped .cb] [winfo viewable .cb] [winfo manager .cb]

} -result [list 1 1 labelframe]

test labelframe-4.2 "Remove nonchild slave" -body {
test labelframe-4.2 "Remove nonchild content" -body {
    .lf configure -labelwidget {}
    update;
    list [winfo ismapped .cb] [winfo viewable .cb] [winfo manager .cb]
} -result [list 0 0 {}]

test labelframe-4.3 "Re-add nonchild slave" -body {
test labelframe-4.3 "Re-add nonchild content" -body {
    .lf configure -labelwidget .cb
    list [update; winfo viewable .cb] [winfo manager .cb]
} -result [list 1 labelframe]

test labelframe-4.4 "Re-manage nonchild slave" -body {
test labelframe-4.4 "Re-manage nonchild content" -body {
    pack .cb -side right
    list [update; winfo viewable .cb] \
    	[winfo manager .cb] \
	[.lf cget -labelwidget]
} -result [list 1 pack {}]

test labelframe-4.5 "Re-add nonchild slave" -body {
test labelframe-4.5 "Re-add nonchild content" -body {
    .lf configure -labelwidget .cb
    list [update; winfo viewable .cb] \
    	[winfo manager .cb] \
	[.lf cget -labelwidget]
} -result [list 1 labelframe .cb]

test labelframe-4.6 "Destroy nonchild slave" -body {
test labelframe-4.6 "Destroy nonchild content" -body {
    destroy .cb
    .lf cget -labelwidget
} -result {}

test labelframe-5.0 "Cleanup" -body {
    destroy .lf
}

# 1342876 -- labelframe should raise sibling -labelwidget above self.
#
test labelframe-6.1 "Stacking order" -body {
    toplevel .t
    pack [ttk::checkbutton .t.x1]
    pack [ttk::labelframe .t.lf -labelwidget [ttk::label .t.lb]]
    pack [ttk::checkbutton .t.x2]
    winfo children .t
} -cleanup {
    destroy .t
} -result [list .t.x1 .t.lf .t.lb .t.x2]

test labelframe-7.1 "style command" -body {
    ttk::labelframe .w
    list [.w cget -style] [.w style] [winfo class .w]
} -cleanup {
    destroy .w
} -result {{} TLabelframe TLabelframe}
test labelframe-7.2 "style command" -body {
    ttk::style configure customStyle.TLabelframe
    ttk::labelframe .w -style customStyle.TLabelframe
    list [.w cget -style] [.w style] [winfo class .w]
} -cleanup {
    destroy .w
} -result {customStyle.TLabelframe customStyle.TLabelframe TLabelframe}

tcltest::cleanupTests

Changes to tests/ttk/layout.test.

1
2



3
4
5
6
7
8
9


1
2
3
4
5
6
7
8
9
10
-
-
+
+
+







package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*
package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test layout-1.1 "Size computations for mixed-orientation layouts" -body {
    ttk::style theme use default

    set block [image create photo -width 10 -height 10]
    ttk::style element create block image $block

Changes to tests/ttk/notebook.test.

1
2



3
4
5
6
7
8
9


1
2
3
4
5
6
7
8
9
10
-
-
+
+
+







package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*
package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test notebook-1.0 "Setup" -body {
    ttk::notebook .nb
} -result .nb

#
20
21
22
23
24
25
26
27

28
29
30
31

32
33
34
35
36
37
38
21
22
23
24
25
26
27

28
29
30
31

32
33
34
35
36
37
38
39







-
+



-
+







    .nb add [frame .sibling]
} -returnCodes error -result "*" -match glob

test notebook-1.3 "Cannot add toplevel" -body {
    .nb add [toplevel .nb.t]
} -cleanup {
    destroy .t.nb
} -returnCodes 1 -match glob -result "can't add .nb.t*"
} -returnCodes error -match glob -result "can't add .nb.t*"

test notebook-1.4 "Try to select bad tab" -body {
    .nb select @6000,6000
} -returnCodes 1 -match glob -result "* not found"
} -returnCodes error -match glob -result "* not found"

#
# Now add stuff:
#
test notebook-2.0 "Add children" -body {
    pack .nb -expand true -fill both
    .nb add [frame .nb.foo] -text "Foo"
507
508
509
510
511
512
513














514
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529







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

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-8.1 "style command" -body {
    ttk::notebook .w
    list [.w cget -style] [.w style] [winfo class .w]
} -cleanup {
    destroy .w
} -result {{} TNotebook TNotebook}
test notebook-8.2 "style command" -body {
    ttk::style configure customStyle.TNotebook
    ttk::notebook .w -style customStyle.TNotebook
    list [.w cget -style] [.w style] [winfo class .w]
} -cleanup {
    destroy .w
} -result {customStyle.TNotebook customStyle.TNotebook TNotebook}

tcltest::cleanupTests

Changes to tests/ttk/panedwindow.test.

1
2



3
4
5
6
7
8
9


1
2
3
4
5
6
7
8
9
10
-
-
+
+
+







package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*
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 {
42
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







-
+








test panedwindow-1.7 "Make sure empty panedwindow still still doesn't crash" -body {
    update
}

test panedwindow-1.8 "Re-forget pane" -body {
    .pw forget .pw.f1
} -returnCodes 1 -result ".pw.f1 is not managed by .pw"
} -returnCodes error -result ".pw.f1 is not managed by .pw"

test panedwindow-1.end "Cleanup" -body {
    destroy .pw
}

# Resize behavior:
#
114
115
116
117
118
119
120
121

122
123
124
125

126
127
128
129
130
131
132
115
116
117
118
119
120
121

122
123
124
125

126
127
128
129
130
131
132
133







-
+



-
+







    .pw add [listbox .pw.lb2]
    .pw pane 1 -weight 2
    .pw pane 1 -weight
} -result 2

test panedwindow-3.1 "configure pane -- errors" -body {
    .pw pane 1 -weight -4
} -returnCodes 1 -match glob -result "-weight must be nonnegative"
} -returnCodes error -match glob -result "-weight must be nonnegative"

test panedwindow-3.2 "add pane -- errors" -body {
    .pw add [ttk::label .pw.l] -weight -1
} -returnCodes 1 -match glob -result "-weight must be nonnegative"
} -returnCodes error -match glob -result "-weight must be nonnegative"


test panedwindow-3.end "cleanup" -body { destroy .pw }


test panedwindow-4.1 "forget" -body {
    pack [ttk::panedwindow .pw -orient vertical] -expand true -fill both
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
143
144
145
146
147
148
149

150
151
152
153
154
155
156
157







-
+







    .pw forget .pw.l3
    .pw forget .pw.l4
    update
}

test panedwindow-4.2 "forget forgotten" -body {
    .pw forget .pw.l1
} -returnCodes 1 -result ".pw.l1 is not managed by .pw"
} -returnCodes error -result ".pw.l1 is not managed by .pw"

# checkorder $winlist --
#	Ensure that Y coordinates windows in $winlist are strictly increasing.
#
proc checkorder {winlist} {
    set pos -1
    set positions [list]
258
259
260
261
262
263
264
265

266
267
268
269
270
271
272
273
274
275
276
277

278
279
280
281
282
283

284
285
286
287
288
289
290


















291
259
260
261
262
263
264
265

266
267
268
269
270
271
272
273
274
275
276
277

278
279
280
281
282
283

284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310







-
+











-
+





-
+







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

test paned-propagation-1 "Initial request size" -body {
    .pw add .pw.f1
    .pw add .pw.f2
    propagate-geometry
    list [winfo reqwidth .pw] [winfo reqheight .pw]
} -result [list 100 105]

test paned-propagation-2 "Slave change before map" -body {
test paned-propagation-2 "Pane change before map" -body {
    .pw.f1 configure -width 200 -height 100
    propagate-geometry
    list [winfo reqwidth .pw] [winfo reqheight .pw]
} -result [list 200 155]

test paned-propagation-3 "Map window" -body {
    pack .pw -expand true -fill both
    update
    list [winfo width .pw] [winfo height .pw] [.pw sashpos 0]
} -result [list 200 155 100]

test paned-propagation-4 "Slave change after map, off-axis" -body {
test paned-propagation-4 "Pane change after map, off-axis" -body {
    .pw.f1 configure -width 100 ;# should be granted
    propagate-geometry
    list [winfo reqwidth .pw] [winfo reqheight .pw] [.pw sashpos 0]
} -result [list 100 155 100]

test paned-propagation-5 "Slave change after map, on-axis" -body {
test paned-propagation-5 "Pane change after map, on-axis" -body {
    .pw.f1 configure -height 50 ;# should be denied
    propagate-geometry
    list [winfo reqwidth .pw] [winfo reqheight .pw] [.pw sashpos 0]
} -result [list 100 155 100]

test paned-propagation-cleanup "Clean up." -body { destroy .pw }

test panedwindow-6.1 "style command" -body {
    # Contrary to ttk::scrollbar, ttk::progressbar and ttk::scale,
    # ttk::panedwindow has same style TPanedwindow whatever -orient is
    ttk::panedwindow .wv  ; # default is  -orient vertical
    ttk::panedwindow .wh -orient horizontal
    list [.wv cget -style] [.wv style] [winfo class .wv]\
         [.wh cget -style] [.wh style] [winfo class .wh]
} -cleanup {
    destroy .wv .wh
} -result {{} TPanedwindow TPanedwindow {} TPanedwindow TPanedwindow}
test panedwindow-6.2 "style command" -body {
    ttk::style configure customStyle.TPanedwindow
    ttk::panedwindow .w -style customStyle.TPanedwindow
    list [.w cget -style] [.w style] [winfo class .w]
} -cleanup {
    destroy .w
} -result {customStyle.TPanedwindow customStyle.TPanedwindow TPanedwindow}

tcltest::cleanupTests

Changes to tests/ttk/progressbar.test.

1
2



3
4
5
6
7
8
9


1
2
3
4
5
6
7
8
9
10
-
-
+
+
+







package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*
package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands


test progressbar-1.1 "Setup" -body {
    ttk::progressbar .pb
} -result .pb

72
73
74
75
76
77
78
79

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

80
81
82
83
84
85
86
87







-
+







    set PB
} -result 6.0

test progressbar-2.5 "error in write trace" -body {
    trace variable PB w { error "YIPES!" ;# }
    .pb step
    set PB		;# NOTREACHED
} -cleanup { unset PB } -returnCodes 1 -match glob -result "*YIPES!"
} -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 {
117
118
119
120
121
122
123
















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







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

    }
    set res
} -cleanup {
    unset res thefont
    destroy .p
} -result {{-anchor e} {-foreground green} {-justify center} {-text {Cannot be seen}} {-wraplength 250}}

test progressbar-4.1 "style command" -body {
    ttk::progressbar .wh  ; # default is  -orient horizontal
    ttk::progressbar .wv -orient vertical
    list [.wh cget -style] [.wh style] [winfo class .wh]\
         [.wv cget -style] [.wv style] [winfo class .wv]
} -cleanup {
    destroy .wh .wv
} -result {{} Horizontal.TProgressbar TProgressbar {} Vertical.TProgressbar TProgressbar}
test progressbar-4.2 "style command" -body {
    ttk::style configure customStyle.Vertical.TProgressbar
    ttk::progressbar .w -orient vertical -style customStyle.Vertical.TProgressbar
    list [.w cget -style] [.w style] [winfo class .w]
} -cleanup {
    destroy .w
} -result {customStyle.Vertical.TProgressbar Vertical.customStyle.Vertical.TProgressbar TProgressbar}

tcltest::cleanupTests

Changes to tests/ttk/radiobutton.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
14




-
-
+
+
+







#
# ttk::radiobutton widget tests.
#

package require Tk
package require tcltest ; namespace import -force tcltest::*
package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test radiobutton-1.1 "Radiobutton check" -body {
    pack \
    	[ttk::radiobutton .rb1 -text "One" -variable choice -value 1] \
	[ttk::radiobutton .rb2 -text "Two" -variable choice -value 2] \
	[ttk::radiobutton .rb3 -text "Three" -variable choice -value 3] \
41
42
43
44
45
46
47














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







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

} -result {0 1 1}

test radiobutton-1.8 "Reset radiobutton variable" -body {
    set ::choice 2
    list [info exists ::choice] [.rb1 instate alternate] [.rb2 instate alternate]
} -result {1 0 0}

test radiobutton-2.1 "style command" -body {
    ttk::radiobutton .w
    list [.w cget -style] [.w style] [winfo class .w]
} -cleanup {
    destroy .w
} -result {{} TRadiobutton TRadiobutton}
test radiobutton-2.2 "style command" -body {
    ttk::style configure customStyle.TRadiobutton
    ttk::radiobutton .w -style customStyle.TRadiobutton
    list [.w cget -style] [.w style] [winfo class .w]
} -cleanup {
    destroy .w
} -result {customStyle.TRadiobutton customStyle.TRadiobutton TRadiobutton}

tcltest::cleanupTests

Added tests/ttk/scale.test.






















































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test scale-1.0 "Self-destruction" -body {
    trace variable v w { destroy .s ;# }
    ttk::scale .s -variable v
    pack .s ; update
    .s set 1 ; update
} -returnCodes error -match glob -result "*"

test scale-2.1 "-state option" -setup {
    ttk::scale .s
    set res ""
} -body {
    # defaults
    lappend res [.s instate disabled] [.s cget -state]
    # set -state: instate returns accordingly
    .s configure -state disabled
    lappend res [.s instate disabled] [.s cget -state]
    # back to normal
    .s configure -state normal
    lappend res [.s instate disabled] [.s cget -state]
    # use state command: -state does NOT reflect it
    .s state disabled
    lappend res [.s instate disabled] [.s cget -state]
    # further use state command
    .s state readonly
    lappend res [.s state] [.s cget -state]
} -cleanup {
    destroy .s
    unset -nocomplain res
} -result {0 normal 1 disabled 0 normal 1 normal {disabled readonly} normal}

test scale-3.1 "style command" -body {
    ttk::scale .wh  ; # default is  -orient horizontal
    ttk::scale .wv -orient vertical
    list [.wh cget -style] [.wh style] [winfo class .wh] \
         [.wv cget -style] [.wv style] [winfo class .wv]
} -cleanup {
    destroy .wh .wv
} -result {{} Horizontal.TScale TScale {} Vertical.TScale TScale}
test scale-3.2 "style command" -body {
    ttk::style configure customStyle.Vertical.TScale
    ttk::scale .w -orient vertical -style customStyle.Vertical.TScale
    list [.w cget -style] [.w style] [winfo class .w]
} -cleanup {
    destroy .w
} -result {customStyle.Vertical.TScale Vertical.customStyle.Vertical.TScale TScale}

tcltest::cleanupTests

Changes to tests/ttk/scrollbar.test.

1
2



3
4
5
6
7
8
9


1
2
3
4
5
6
7
8
9
10
-
-
+
+
+







package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*
package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

testConstraint coreScrollbar [expr {[tk windowingsystem] eq "aqua"}]

# Before 2019 the code in library/ttk/scrollbar.tcl would replace the
# constructor of ttk::scrollbar with the constructor of tk::scrollbar
# unless the -class or -style options were specified..
66
67
68
69
70
71
72
73

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

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

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

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

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


145
146
147


148
149

150
151
152
153
154


155
156
157
158



159
160
161
162

163
164
165
166
167
168
169

170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187

188
189

190
191

192
193
194
67
68
69
70
71
72
73

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

87














88

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

102















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


116
117



118
119


120





121
122
123



124
125
126




127







128


















129
130

131


132
133
134
135







-
+












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

-
+












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












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

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

-
+
-
-
+



    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} -constraints {notAqua} -setup {
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}
} -result {4.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 [ttk::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.1 {<Shift-MouseWheel> event on horizontal scrollbar} -constraints {notAqua} -setup {
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}
} -result {1.3}
test scrollbar-10.2.2 {<Shift-MouseWheel> event on horizontal 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 [ttk::scrollbar .s -command {.t xview} -orient horizontal] -fill x -expand 1 -side top
    update
    focus -force .s
    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-10.2.3 {<MouseWheel> event on horizontal scrollbar} -constraints {notAqua} -setup {
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}
test scrollbar-10.2.4 {<MouseWheel> event on horizontal scrollbar} -constraints {aqua} -setup {
} -result {1.3}

    destroy .t .s
} -body {
    pack [text .t -xscrollcommand {.s set} -wrap none] -side top
test scrollbar-11.1 "style command" -body {
    ttk::scrollbar .wv  ; # default is  -orient vertical
    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
    ttk::scrollbar .wh -orient horizontal
    update
    focus -force .s
    event generate .s <MouseWheel> -delta -4
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
    list [.wv cget -style] [.wv style] [winfo class .wv] \
         [.wh cget -style] [.wh style] [winfo class .wh]
} -cleanup {
    destroy .t .s
} -result {1.4}

    destroy .wv .wh
} -result {{} Vertical.TScrollbar TScrollbar {} Horizontal.TScrollbar TScrollbar}
test scrollbar-11.2 "style command" -body {
#
# Scale tests:
#

    ttk::style configure customStyle.Horizontal.TScrollbar
test scale-1.0 "Self-destruction" -body {
    trace variable v w { destroy .s ;# }
    ttk::scale .s -variable v
    pack .s ; update
    .s set 1 ; update
} -returnCodes 1 -match glob -result "*"

    ttk::scrollbar .w -orient horizontal -style customStyle.Horizontal.TScrollbar
test scale-2.1 "-state option" -setup {
    ttk::scale .s
    set res ""
} -body {
    # defaults
    lappend res [.s instate disabled] [.s cget -state]
    # set -state: instate returns accordingly
    .s configure -state disabled
    lappend res [.s instate disabled] [.s cget -state]
    # back to normal
    .s configure -state normal
    lappend res [.s instate disabled] [.s cget -state]
    # use state command: -state does NOT reflect it
    .s state disabled
    lappend res [.s instate disabled] [.s cget -state]
    # further use state command
    .s state readonly
    lappend res [.s state] [.s cget -state]
    list [.w cget -style] [.w style] [winfo class .w]
} -cleanup {
    destroy .s
    destroy .w
    unset -nocomplain res
} -result {0 normal 1 disabled 0 normal 1 normal {disabled readonly} normal}
} -result {customStyle.Horizontal.TScrollbar Horizontal.customStyle.Horizontal.TScrollbar TScrollbar}

tcltest::cleanupTests

Changes to tests/ttk/spinbox.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
14




-
-
+
+
+







#
# ttk::spinbox widget tests
#

package require Tk
package require tcltest ; namespace import -force tcltest::*
package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test spinbox-1.0 "Spinbox tests -- setup" -body {
    ttk::spinbox .sb
} -cleanup { destroy .sb } -result .sb

test spinbox-1.1 "Bad -values list" -setup {
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







-
+







    .sb configure -validate focus
    .sb configure -validate focusin
    .sb configure -validate focusout
    .sb configure -validate none
    .sb cget -validate
} -cleanup {
    destroy .sb
} -result {none}
} -result none

test spinbox-1.8.3 "option -validate" -setup {
    ttk::spinbox .sb -from 0 -to 100
} -body {
    .sb configure -validate bogus
} -cleanup {
    destroy .sb
200
201
202
203
204
205
206
207
208


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

220
221
222
223
224
225
226
227







-

+
+



+
-
+



+
-
+







} -result -1

test spinbox-3.0 "textarea should expand to fill widget" -setup {
    set SBV 5
    set ::spinbox_test {}
    ttk::spinbox .sb -from 0 -to 10 -textvariable SBV
} -body {
    grid .sb -sticky ew
    grid columnconfigure . 0 -weight 1
    update idletasks
    set timer [after 500 {set ::spinbox_test timedout}]
    bind . <Map> {
        after idle {
            wm geometry . "210x80"
	    update idletasks
            after 100 {set ::spinbox_test [.sb identify element 5 5]}
            set ::spinbox_test [.sb identify element 25 5]
        }
        bind . <Map> {}
    }
    grid .sb -sticky ew
    after 500 {set ::spinbox_wait 1} ; vwait ::spinbox_wait
    vwait ::spinbox_test
    set ::spinbox_test
} -cleanup {
    destroy .sb
    unset -nocomplain ::spinbox_test SBV
} -result {textarea}

test spinbox-4.0 "Increment with duplicates in -values, wrap" -setup {
350
351
352
353
354
355
356














357
358
359
360
361
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379







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





    event generate .sb <<Increment>> ; lappend result [.sb get]
    .sb set asdfasdf ; lappend result [.sb get]
    event generate .sb <<Decrement>> ; lappend result [.sb get]
} -result [list asdfasdf 000 asdfasdf 000] -cleanup {
    destroy .sb
}

test spinbox-5.1 "style command" -body {
    ttk::spinbox .w
    list [.w cget -style] [.w style] [winfo class .w]
} -cleanup {
    destroy .w
} -result {{} TSpinbox TSpinbox}
test spinbox-5.2 "style command" -body {
    ttk::style configure customStyle.TSpinbox
    ttk::spinbox .w -style customStyle.TSpinbox
    list [.w cget -style] [.w style] [winfo class .w]
} -cleanup {
    destroy .w
} -result {customStyle.TSpinbox customStyle.TSpinbox TSpinbox}

tcltest::cleanupTests

# Local variables:
# mode: tcl
# End:

Changes to tests/ttk/treetags.test.

1
2
3



4
5
6
7
8
9
10
1


2
3
4
5
6
7
8
9
10
11

-
-
+
+
+








package require Tk
package require tcltest ; namespace import -force tcltest::*
package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

### treeview tag invariants:
#

proc assert {expr {message ""}} {
    if {![uplevel 1 [list expr $expr]]} {
166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
167
168
169
170
171
172
173

174
175
176
177
178
179
180
181







-
+







    set bong
} -cleanup {
    treeConstraints $tv
} -result 1

test treetags-2.4 "Bad events" -body {
    $tv tag bind bad <Enter> { puts "Entered!" }
} -returnCodes 1 -result "unsupported event <Enter>*" -match glob
} -returnCodes error -result "unsupported event <Enter>*" -match glob

test treetags-3.0 "tag configure - set" -body {
    $tv tag configure tag1 -foreground blue -background red
} -cleanup {
    treeConstraints $tv
} -result {}

Changes to tests/ttk/treeview.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
15





-
-
+
+
+







#
# [7Jun2005] TO CHECK: [$tv see {}] -- shouldn't work (at least, shouldn't do
# what it currently does)
#

package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*
package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

# consistencyCheck --
#	Traverse the tree to make sure the item data structures
#	are properly linked.
#
#	Since [$tv children] follows ->next links and [$tv index]
41
42
43
44
45
46
47
48

49
50
51
52

53
54
55
56

57
58
59
60

61
62
63
64
65
66

67
68
69
70

71
72
73
74

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

87
88
89
90
91
92
93
42
43
44
45
46
47
48

49
50
51
52

53
54
55
56

57
58
59
60

61
62
63
64
65
66

67
68
69
70

71
72
73
74

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

87
88
89
90
91
92
93
94







-
+



-
+



-
+



-
+





-
+



-
+



-
+











-
+







test treeview-1.1 "columns" -body {
    .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 1 -result "list element in quotes followed by*" -match glob
} -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 1 -result "Invalid column index d"
} -returnCodes error -result "Invalid column index d"

test treeview-1.4 "more bad displaycolumns" -body {
    .tv configure -displaycolumns {1 2 3}
} -returnCodes 1 -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 1 -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 1 -result "wrong # args: *" -match glob
} -returnCodes error -result "wrong # args: *" -match glob

test treeview-2.3 "insert -- bad integer index" -body {
    .tv insert {} badindex
} -returnCodes 1 -result "expected integer *" -match glob
} -returnCodes error -result "expected integer *" -match glob

test treeview-2.4 "insert -- bad parent node" -body {
    .tv insert badparent end
} -returnCodes 1 -result "Item badparent not found" -match glob
} -returnCodes error -result "Item badparent not found" -match glob

test treeview-2.5 "insert -- finaly insert a node" -body {
    .tv insert {} end -id newnode -text "New node"
} -result newnode

test treeview-2.6 "insert -- make sure node was inserted" -body {
    .tv children {}
} -result [list newnode]

test treeview-2.7 "insert -- prevent duplicate node names" -body {
    .tv insert {} end -id newnode
} -returnCodes 1 -result "Item newnode already exists"
} -returnCodes error -result "Item newnode already exists"

test treeview-2.8 "insert -- new node at end" -body {
    .tv insert {} end -id lastnode
    consistencyCheck .tv
    .tv children {}
} -result [list newnode lastnode]

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







-
+







    .tv insert {} 0 -id newfirstone
    consistencyCheck .tv
    .tv children {}
} -result [list newfirstone firstnode newnode anotherone onemore lastnode newlastone]

test treeview-2.14 "insert -- bad options" -body {
    .tv insert {} end -badoption foo
} -returnCodes 1 -result {unknown option "-badoption"}
} -returnCodes error -result {unknown option "-badoption"}

test treeview-2.15 "insert -- at position 0 w/no children" -body {
    .tv insert newnode 0 -id newnode.n2 -text "Foo"
    .tv children newnode
} -result newnode.n2	;# don't crash

test treeview-2.16 "insert -- insert way past end" -body {
197
198
199
200
201
202
203
204

205
206
207
208
209
210
211
198
199
200
201
202
203
204

205
206
207
208
209
210
211
212







-
+







    .tv children {}
} -result [list newfirstone firstnode anotherone onemore lastnode newlastone]

test treeview-3.11 "Can't detach root item" -body {
    .tv detach [list {}]
    update
    consistencyCheck .tv
} -returnCodes 1 -result "Cannot detach root item"
} -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]
270
271
272
273
274
275
276
277

278
279
280
281
282
283
284
271
272
273
274
275
276
277

278
279
280
281
282
283
284
285







-
+







test treeview-4.3 "opened - closed node" -body {
    .tv item newnode -open 0
    .tv item newnode -open
} -result 0

test treeview-5.1 "item -- error checks" -body {
    .tv item newnode -text "Bad values" -values "{bad}list"
} -returnCodes 1 -result "list element in braces followed by*" -match glob
} -returnCodes error -result "list element in braces followed by*" -match glob

test treeview-5.2 "item -- error leaves options unchanged " -body {
    .tv item newnode -text
} -result "New node"

test treeview-5.3 "Heading" -body {
    .tv heading #0 -text "Heading"
293
294
295
296
297
298
299
300

301
302
303
304

305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320

321
322
323
324
325
326
327
294
295
296
297
298
299
300

301
302
303
304

305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320

321
322
323
324
325
326
327
328







-
+



-
+















-
+







test treeview-5.5 "set cell" -body {
    .tv set newnode 1 XXX
    .tv item newnode -values
} -result [list a XXX c]

test treeview-5.6 "set illegal cell" -body {
    .tv set newnode #0 YYY
} -returnCodes 1 -result "Display column #0 cannot be set"
} -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 1 -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
} -result [list Z Y X]

test treeview-5.9 "display columns part 2" -body {
    list [.tv column #1 -id] [.tv column #2 -id] [.tv column #3 -id]
} -result [list c b a]

test treeview-5.10 "cannot set column -id" -body {
    .tv column #1 -id X
} -returnCodes 1 -result "Attempt to change read-only option"
} -returnCodes error -result "Attempt to change read-only option"

test treeview-5.11 "get" -body {
    .tv set newnode #1
} -result X

test treeview-5.12 "get dictionary" -body {
    .tv set newnode
401
402
403
404
405
406
407
408

409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429

430
431
432
433
434
435
436
402
403
404
405
406
407
408

409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429

430
431
432
433
434
435
436
437







-
+




















-
+







    .tv move d3 d 0
    consistencyCheck .tv
    .tv children d
} -result [list d3 d1 d2]

test treeview-7.2 "illegal move" -body {
   .tv move d d2 end
} -returnCodes 1 -result "Cannot insert d as descendant of d2"
} -returnCodes error -result "Cannot insert d as descendant of d2"

test treeview-7.3 "illegal move has no effect" -body {
    consistencyCheck .tv
    .tv children d
} -result [list d3 d1 d2]

test treeview-7.4 "Replace children" -body {
    .tv children d [list d3 d2 d1]
    consistencyCheck .tv
    .tv children d
} -result [list d3 d2 d1]

test treeview-7.5 "replace children - precondition" -body {
    # 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 1 -result "Cannot insert newnode.n1 as descendant of newnode.n1"
} -returnCodes error -result "Cannot insert newnode.n1 as descendant of newnode.n1"

consistencyCheck .tv

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







-
+







test treeview-8.4 "Selection - clear" -body {
    .tv selection set {}
    .tv selection
} -result {}

test treeview-8.5 "Selection - bad operation" -body {
    .tv selection badop foo
} -returnCodes 1 -match glob -result {bad selection operation "badop": must be *}
} -returnCodes error -match glob -result {bad selection operation "badop": must be *}

test treeview-8.6 "Selection - <<TreeviewSelect>> on selection add" -body {
    .tv selection set {}
    bind .tv <<TreeviewSelect>> {set res 1}
    set res 0
    .tv selection add newnode.n1
    update
830
831
832
833
834
835
836














837
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852







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

    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-11.1 "style command" -body {
    ttk::treeview .w
    list [.w cget -style] [.w style] [winfo class .w]
} -cleanup {
    destroy .w
} -result {{} Treeview Treeview}
test treeview-11.2 "style command" -body {
    ttk::style configure customStyle.Treeview
    ttk::treeview .w -style customStyle.Treeview
    list [.w cget -style] [.w style] [winfo class .w]
} -cleanup {
    destroy .w
} -result {customStyle.Treeview customStyle.Treeview Treeview}

tcltest::cleanupTests

Changes to tests/ttk/ttk.test.

1
2
3



4
5
6
7
8
9
10
1


2
3
4
5
6
7
8
9
10
11

-
-
+
+
+








package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*
package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

proc skip args {}
proc ok {} { return }

variable widgetClasses {
    button checkbutton radiobutton menubutton label entry
27
28
29
30
31
32
33
34

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

35
36
37
38
39
40
41
42







-
+







    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]
    update
    .sd invoke
} -returnCodes 1
} -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 {
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156







-
+








test ttk-1.2 "Check style" -body {
    .t cget -style
} -result {}

test ttk-1.3 "Set bad style" -body {
    .t configure -style "nosuchstyle"
} -returnCodes 1 -result {Layout nosuchstyle not found}
} -returnCodes error -result {Layout nosuchstyle not found}

test ttk-1.4 "Original style preserved" -body {
    .t cget -style
} -result ""

proc checkstate {w} {
    foreach statespec {
230
231
232
233
234
235
236
237

238
239
240
241

242
243
244
245
246
247
248
249
250
251
252
253
254

255
256
257
258
259
260
261
231
232
233
234
235
236
237

238
239
240
241

242
243
244
245
246
247
248
249
250
251
252
253
254

255
256
257
258
259
260
261
262







-
+



-
+












-
+







	catch {destroy .w}
    }
}

# misc. error detection
test ttk-3.0 "Bad option" -body {
    ttk::button .bad -badoption foo
} -returnCodes 1 -result {unknown option "-badoption"} -match glob
} -returnCodes error -result {unknown option "-badoption"} -match glob

test ttk-3.1 "Make sure widget command not created" -body {
    .bad state disabled
} -returnCodes 1 -result {invalid command name ".bad"} -match glob
} -returnCodes error -result {invalid command name ".bad"} -match glob

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}

test ttk-3.3 "Constructor failure with cursor" -body {
    ttk::button .b -cursor bottom_right_corner -style BadStyle
} -returnCodes 1 -result "Layout BadStyle not found"
} -returnCodes error -result "Layout BadStyle not found"

test ttk-3.4 "SF#2009213" -body {
    ttk::style configure TScale -sliderrelief {}
    pack [ttk::scale .s]
    update
} -cleanup {
    ttk::style configure TScale -sliderrelief raised
383
384
385
386
387
388
389
390

391
392
393
394
395

396
397
398
399
400
401
402
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 1 -result "*parent namespace doesn't exist*" -match glob
} -returnCodes error -result "*parent namespace doesn'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 1 -result "*parent namespace doesn't exist*" -match glob
} -returnCodes error -result "*parent namespace doesn'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..."
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







-
+








test ttk-10.3 "Check class resource" -body {
    .f cget -class
} -result Foo

test ttk-10.4 "Try to modify class resource" -body {
    .f configure -class Bar
} -returnCodes 1 -match glob -result "*read-only option*"
} -returnCodes error -match glob -result "*read-only option*"

test ttk-10.5 "Check class resource again" -body {
    .f cget -class
} -result Foo

test ttk-11.1 "-state test, setup" -body {
    ttk::button .b
543
544
545
546
547
548
549
550

551
552
553
554
555
556
557

558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575

576
577
578
579
580

581
582
583
584
585

586
587
588
589
590
591
592
544
545
546
547
548
549
550

551
552
553
554
555
556
557

558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575

576
577
578
579
580

581
582
583
584
585

586
587
588
589
590
591
592
593







-
+






-
+

















-
+




-
+




-
+







    .t.f configure -borderwidth 1
    ttk::style theme use alt
    update
}

test ttk-13.1 "Custom styles -- bad -style option" -body {
    ttk::button .tb1 -style badstyle
} -returnCodes 1 -result "*badstyle not found*" -match glob
} -returnCodes error -result "*badstyle not found*" -match glob

test ttk-13.4 "Custom styles -- bad -style option" -body {
    ttk::button .tb1
    .tb1 configure -style badstyle
} -cleanup {
    destroy .tb1
} -returnCodes 1 -result "*badstyle not found*" -match glob
} -returnCodes error -result "*badstyle not found*" -match glob

test ttk-13.5 "Custom layouts -- missing element definition" -body {
    ttk::style layout badstyle {
    	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 1 -result {can't trace *: parent namespace doesn't exist} \
} -returnCodes error -result {can't trace *: parent namespace doesn't exist} \
  -match glob -cleanup { destroy .tw }

test ttk-14.2 "-textvariable in nonexistant namespace" -body {
    ttk::label .tw -textvariable ::nsn::foo
} -returnCodes 1 -result {can't trace *: parent namespace doesn't exist} \
} -returnCodes error -result {can't trace *: parent namespace doesn't exist} \
  -match glob -cleanup { destroy .tw }

test ttk-14.3 "-textvariable in nonexistant namespace" -body {
    ttk::entry .tw -textvariable ::nsn::foo
} -returnCodes 1 -result {can't trace *: parent namespace doesn't exist} \
} -returnCodes error -result {can't trace *: parent namespace doesn't exist} \
  -match glob -cleanup { destroy .tw }

test ttk-15.1 {Bug 3062331} -setup {
    destroy .b
} -body {
    set Y {}
    ttk::button .b -textvariable Y
624
625
626
627
628
629
630
631

632
633
634
635
636

637
638
639
640
641

642
643
644
645
646

647
648
649
650
651

652
653
654
655











656
657
658
659
660
661
625
626
627
628
629
630
631

632
633
634
635
636

637
638
639
640
641

642
643
644
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







-
+




-
+




-
+




-
+




-
+




+
+
+
+
+
+
+
+
+
+
+






    set usage $args
    append usage " ?$varpart ...?"
    return "wrong # args: should be \"$usage\""
}

test ttk-ensemble-0 "style element create: insufficient args" -body {
     ttk::style
} -returnCodes 1 -result \
} -returnCodes error -result \
    [wrong#varargs arg ttk::style option]

test ttk-ensemble-1 "style element create: insufficient args" -body {
     ttk::style element
} -returnCodes 1 -result \
} -returnCodes error -result \
    [wrong#varargs arg ttk::style element option]

test ttk-ensemble-2 "style element create: insufficient args" -body {
     ttk::style element create
} -returnCodes 1 -result \
} -returnCodes error -result \
    [wrong#varargs {-option value} ttk::style element create name type]

test ttk-ensemble-3 "style element create: insufficient args" -body {
     ttk::style element create plain.background
} -returnCodes 1 -result \
} -returnCodes error -result \
    [wrong#varargs {-option value} ttk::style element create name type]

test ttk-ensemble-4 "style element create: insufficient args" -body {
     ttk::style element create plain.background from
} -returnCodes 1 -result [wrong#args theme ?element?]
} -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 ""

test ttk-16.1 {ttk::style theme styles - no such theme} -body {
    ttk::style theme styles noSuchTheme
} -returnCodes 1 -result {theme "noSuchTheme" doesn't exist}
test ttk-16.2 {ttk::style theme styles - theme exists} -body {
    # simply check this produces a list with some style names,
    # without checking exact content (not needed, and may vary
    # depending on platform, versions, improvements...)
    expr {[llength [ttk::style theme styles alt]] > 0}
} -result 1


eval destroy [winfo children .]

tcltest::cleanupTests

#*EOF*

Changes to tests/ttk/validate.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





-
-
+
+







##
## Entry widget validation tests
## Derived from core test suite entry-19.1 through entry-19.20
##

package require Tk 8.5
package require tcltest 2.1
package require tk
package require tcltest 2.2
namespace import -force tcltest::*

loadTestedCommands

testConstraint ttkEntry 1
testConstraint coreEntry [expr {![testConstraint ttkEntry]}]

Changes to tests/ttk/vsapi.test.

1
2
3
4
5



6
7
8
9

10
11
12
13
14
15
16
1
2
3


4
5
6
7
8
9

10
11
12
13
14
15
16
17



-
-
+
+
+



-
+







# -*- tcl -*-
#

package require Tk 8.5
package require tcltest ; namespace import -force tcltest::*
package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

testConstraint xpnative \
    [expr {[lsearch -exact [ttk::style theme names] xpnative] != -1}]
    [expr {"xpnative" in [ttk::style theme names]}]

test vsapi-1.1 "WINDOW WP_SMALLCLOSEBUTTON" -constraints {xpnative} -body {
    ttk::style element create smallclose vsapi \
        WINDOW 19 {disabled 4 pressed 3 active 2 {} 1}
    ttk::style layout CloseButton {CloseButton.smallclose -sticky news}
    ttk::button .b -style CloseButton
    pack .b -expand true -fill both

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 (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 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
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
29




-
-
+
+







+
+
+





-
+







# This file is a Tcl script to test out the procedures in the file
# tkUnixEmbed.c.  It is organized in the standard fashion for Tcl
# tests.
#
# Copyright (c) 1996-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1996-1997 Sun Microsystems, Inc.
# Copyright © 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(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
# ------------------------------------------------------------------------------
# Command that creates an unsafe child interpreter and tries to load Tk.
# Command that creates an child interpreter and tries to load Tk.
# This code is borrowed from safePrimarySelection.test
# This is necessary for loading Tktest if the tests are done in the build
# directory without installing Tk.  In that case the usual auto_path loading
# mechanism cannot work because the tk binary is not where pkgIndex.tcl says
# it is.
# ------------------------------------------------------------------------------

146
147
148
149
150
151
152
153
154
155



156
157
158
159
160
161


162
163
164
165
166
167

168
169
170
171
172
173
174
149
150
151
152
153
154
155



156
157
158
159
160
161
162


163
164
165
166
167
168
169

170
171
172
173
174
175
176
177







-
-
-
+
+
+




-
-
+
+





-
+







} -cleanup {
	deleteWindows
} -result {{{XXX {} {} .t}} 0}
test unixEmbed-1.5a {TkpUseWindow procedure, creating Container records} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete slave}
    ::_test_tmp::testInterp slave
    load {} Tktest slave
    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
    slave alias w winfo id .f1
    slave eval {
    child alias w winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t -use [w]
        list [testembed] [expr {[lindex [lindex [testembed all] 0] 0] - [w]}]
    }
} -cleanup {
    interp delete slave
    interp delete child
    deleteWindows
} -result {{{XXX {} {} .t}} 0}
test unixEmbed-1.6 {TkpUseWindow procedure, creating Container records} -constraints {
	unix testembed notAqua
} -setup {
	deleteWindows
} -body {
186
187
188
189
190
191
192
193
194
195



196
197
198
199
200
201
202



203
204
205
206
207
208
209

210
211
212
213
214
215
216
189
190
191
192
193
194
195



196
197
198
199
200
201
202



203
204
205
206
207
208
209
210
211

212
213
214
215
216
217
218
219







-
-
-
+
+
+




-
-
-
+
+
+






-
+







} -cleanup {
	deleteWindows
} -result {{XXX {} {} .t2} {XXX {} {} .t1}}
test unixEmbed-1.6a {TkpUseWindow procedure, creating Container records} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete slave}
    ::_test_tmp::testInterp slave
    load {} Tktest slave
    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
    slave alias w1 winfo id .f1
    slave alias w2 winfo id .f2
    slave eval {
    child alias w1 winfo id .f1
    child alias w2 winfo id .f2
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        toplevel .t2 -use [w2]
        testembed
    }
} -cleanup {
    interp delete slave
    interp delete child
    deleteWindows
} -result {{XXX {} {} .t2} {XXX {} {} .t1}}
test unixEmbed-1.7 {TkpUseWindow procedure, container and embedded in same app} -constraints {
	unix testembed
} -setup {
	deleteWindows
} -body {
249
250
251
252
253
254
255
256
257
258



259
260
261
262
263


264
265
266
267
268
269
270

271
272
273
274
275
276
277
252
253
254
255
256
257
258



259
260
261
262
263
264


265
266
267
268
269
270
271
272

273
274
275
276
277
278
279
280







-
-
-
+
+
+



-
-
+
+






-
+







} -cleanup {
	deleteWindows
} -result {}
test unixEmbed-2.1a {EmbeddedEventProc procedure} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete slave}
    ::_test_tmp::testInterp slave
    load {} Tktest slave
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    slave alias w1 winfo id .f1
    slave eval {
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        testembed
    }
    destroy .f1
    update
    slave eval {
    child eval {
        testembed
    }
} -cleanup {
    deleteWindows
} -result {}
test unixEmbed-2.2 {EmbeddedEventProc procedure} -constraints {
	unix testembed notAqua
291
292
293
294
295
296
297
298
299
300



301
302
303
304
305


306
307
308
309
310
311
312
313

314
315
316
317
318
319
320
294
295
296
297
298
299
300



301
302
303
304
305
306


307
308
309
310
311
312
313
314
315

316
317
318
319
320
321
322
323







-
-
-
+
+
+



-
-
+
+







-
+







} -cleanup {
	deleteWindows
} -result {}
test unixEmbed-2.2a {EmbeddedEventProc procedure} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete slave}
    ::_test_tmp::testInterp slave
    load {} Tktest slave
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    slave alias w1 winfo id .f1
    slave eval {
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        testembed
        destroy .t1
        testembed
    }
} -cleanup {
    interp delete slave
    interp delete child
    deleteWindows
} -result {}
test unixEmbed-2.3 {EmbeddedEventProc procedure} -constraints {
	unix testembed notAqua
} -setup {
	deleteWindows
} -body {
357
358
359
360
361
362
363
364
365
366



367
368
369
370

371
372

373
374
375
376
377
378
379

380
381
382
383
384
385
386
360
361
362
363
364
365
366



367
368
369
370
371
372

373
374

375
376
377
378
379
380
381

382
383
384
385
386
387
388
389







-
-
-
+
+
+



-
+

-
+






-
+







    list $x [testembed]
} -cleanup {
	deleteWindows
} -result {{{XXX .f1 {} {}}} {{XXX .f1 XXX {}}}}
test unixEmbed-3.1a {ContainerEventProc procedure, detect creation} -constraints {
    unix testembed
} -setup {
    catch {interp delete slave}
    ::_test_tmp::testInterp slave
    load {} Tktest slave
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    slave alias w1 winfo id .f1
    child alias w1 winfo id .f1
    set x [testembed]
    slave eval {
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        wm withdraw .t1
    }
    list $x [testembed]
} -cleanup {
    interp delete slave
    interp delete child
    deleteWindows
} -result {{{XXX .f1 {} {}}} {{XXX .f1 {} {}}}}
test unixEmbed-3.2 {ContainerEventProc procedure, set size on creation} -constraints {
	unix
} -setup {
	deleteWindows
    update
414
415
416
417
418
419
420
421
422
423



424
425
426
427
428


429
430
431
432
433
434
435
436
437

438
439
440
441
442
443
444
417
418
419
420
421
422
423



424
425
426
427
428
429


430
431
432
433
434
435
436
437
438
439

440
441
442
443
444
445
446
447







-
-
-
+
+
+



-
-
+
+








-
+







} -cleanup {
	deleteWindows
} -result {200x200+0+0}
test unixEmbed-3.3a {ContainerEventProc procedure, disallow position changes} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete slave}
    ::_test_tmp::testInterp slave
    load {} Tktest slave
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    slave alias w1 winfo id .f1
    slave eval {
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1] -bd 2 -relief raised
        update
        wm geometry .t1 +30+40
        update
        wm geometry .t1
    }
} -cleanup {
    interp delete slave
    interp delete child
    deleteWindows
} -result {200x200+0+0}
test unixEmbed-3.4 {ContainerEventProc procedure, disallow position changes} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
458
459
460
461
462
463
464
465
466
467



468
469
470
471
472


473
474
475
476
477
478
479
480
481

482
483
484
485
486
487
488
461
462
463
464
465
466
467



468
469
470
471
472
473


474
475
476
477
478
479
480
481
482
483

484
485
486
487
488
489
490
491







-
-
-
+
+
+



-
-
+
+








-
+







} -cleanup {
	deleteWindows
} -result {300x100+0+0}
test unixEmbed-3.4a {ContainerEventProc procedure, disallow position changes} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete slave}
    ::_test_tmp::testInterp slave
    load {} Tktest slave
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    slave alias w1 winfo id .f1
    slave eval {
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        update
        wm geometry .t1 300x100+30+40
        update
        wm geometry .t1
    }
} -cleanup {
    interp delete slave
    interp delete child
    deleteWindows
} -result {300x100+0+0}
test unixEmbed-3.5 {ContainerEventProc procedure, geometry requests} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
502
503
504
505
506
507
508
509
510
511



512
513
514
515
516


517
518
519
520
521
522

523
524

525
526
527
528
529
530
531
505
506
507
508
509
510
511



512
513
514
515
516
517


518
519
520
521
522
523
524

525
526

527
528
529
530
531
532
533
534







-
-
-
+
+
+



-
-
+
+





-
+

-
+







} -cleanup {
	deleteWindows
} -result {300 80 300x80+0+0}
test unixEmbed-3.5a {ContainerEventProc procedure, geometry requests} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete slave}
    ::_test_tmp::testInterp slave
    load {} Tktest slave
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    slave alias w1 winfo id .f1
    slave eval {
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        .t1 configure -width 300 -height 80
        update
    }
    list [winfo width .f1] [winfo height .f1] [slave eval {wm geometry .t1}]
    list [winfo width .f1] [winfo height .f1] [child eval {wm geometry .t1}]
} -cleanup {
    interp delete slave
    interp delete child
    deleteWindows
} -result {300 80 300x80+0+0}
test unixEmbed-3.6 {ContainerEventProc procedure, map requests} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
547
548
549
550
551
552
553
554
555
556



557
558
559
560
561


562
563
564
565
566
567
568
569
570
571
572

573
574
575
576
577
578
579
550
551
552
553
554
555
556



557
558
559
560
561
562


563
564
565
566
567
568
569
570
571
572
573
574

575
576
577
578
579
580
581
582







-
-
-
+
+
+



-
-
+
+










-
+







} -cleanup {
	deleteWindows
} -result {mapped}
test unixEmbed-3.6a {ContainerEventProc procedure, map requests} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete slave}
    ::_test_tmp::testInterp slave
    load {} Tktest slave
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    slave alias w1 winfo id .f1
    slave eval {
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        set x unmapped
        bind .t1 <Map> {set x mapped}
        update
        after 100
        update
        set x
    }
} -cleanup {
    interp delete slave
    interp delete child
    deleteWindows
} -result {mapped}
test unixEmbed-3.7 {ContainerEventProc procedure, destroy events} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
595
596
597
598
599
600
601
602
603
604



605
606
607
608

609
610
611

612
613
614
615
616
617
618
619
620

621
622
623
624
625
626
627
598
599
600
601
602
603
604



605
606
607
608
609
610

611
612
613

614
615
616
617
618
619
620
621
622

623
624
625
626
627
628
629
630







-
-
-
+
+
+



-
+


-
+








-
+







} -cleanup {
	deleteWindows
} -result {dead 0}
test unixEmbed-3.7a {ContainerEventProc procedure, destroy events} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete slave}
    ::_test_tmp::testInterp slave
    load {} Tktest slave
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    slave alias w1 winfo id .f1
    child alias w1 winfo id .f1
    bind .f1 <Destroy> {set x dead}
    set x alive
    slave eval {
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        update
        destroy .t1
    }
    update
    list $x [winfo exists .f1]
} -cleanup {
    interp delete slave
    interp delete child
    deleteWindows
} -result {dead 0}

test unixEmbed-4.1 {EmbedStructureProc procedure, configure events} -constraints {
	unix notAqua
} -setup {
	deleteWindows
644
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
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







-
-
-
+
+
+



-
-
+
+








-
+







} -cleanup {
	deleteWindows
} -result {180x100+0+0}
test unixEmbed-4.1a {EmbedStructureProc procedure, configure events} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete slave}
    ::_test_tmp::testInterp slave
    load {} Tktest slave
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    slave alias w1 winfo id .f1
    slave eval {
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        update
        .t1 configure -width 180 -height 100
        update
        winfo geometry .t1
    }
} -cleanup {
    interp delete slave
    interp delete child
    deleteWindows
} -result {180x100+0+0}
test unixEmbed-4.2 {EmbedStructureProc procedure, destroy events} -constraints {
	unix testembed notAqua
} -setup {
	deleteWindows
} -body {
687
688
689
690
691
692
693
694
695
696



697
698
699
700
701
702


703
704
705
706
707
708
709
710

711
712
713
714
715
716
717
690
691
692
693
694
695
696



697
698
699
700
701
702
703


704
705
706
707
708
709
710
711
712

713
714
715
716
717
718
719
720







-
-
-
+
+
+




-
-
+
+







-
+







} -cleanup {
	deleteWindows
} -result {{{XXX .f1 XXX {}}} {}}
test unixEmbed-4.2a {EmbedStructureProc procedure, destroy events} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete slave}
    ::_test_tmp::testInterp slave
    load {} Tktest slave
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    update
    slave alias w1 winfo id .f1
    slave eval {
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
    }
    set x [testembed]
    destroy .f1
    list $x [testembed]
} -cleanup {
    interp delete slave
    interp delete child
    deleteWindows
} -result "{{XXX .f1 {} {}}} {}"


test unixEmbed-5.1 {EmbedFocusProc procedure, FocusIn events} -constraints {
	unix notAqua
} -setup {
733
734
735
736
737
738
739
740
741
742



743
744
745
746
747


748
749
750
751
752
753
754
755
756
757

758
759

760
761
762
763
764
765
766
736
737
738
739
740
741
742



743
744
745
746
747
748


749
750
751
752
753
754
755
756
757
758
759

760
761

762
763
764
765
766
767
768
769







-
-
-
+
+
+



-
-
+
+









-
+

-
+







} -cleanup {
	deleteWindows
} -result {{focus in .t1}}
test unixEmbed-5.1a {EmbedFocusProc procedure, FocusIn events} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete slave}
    ::_test_tmp::testInterp slave
    load {} Tktest slave
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    slave alias w1 winfo id .f1
    slave eval {
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        bind .t1 <FocusIn> {lappend x "focus in %W"}
        bind .t1 <FocusOut> {lappend x "focus out %W"}
        update
        set x {}
    }
    focus -force .f1
    update
    slave eval {set x}
    child eval {set x}
} -cleanup {
    interp delete slave
    interp delete child
    deleteWindows
} -result {{focus in .t1}}
test unixEmbed-5.2 {EmbedFocusProc procedure, focusing on dead window} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
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
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







-
-
-
+
+
+



-
-
+
+









-
+







} -cleanup {
	deleteWindows
} -result {}
test unixEmbed-5.2a {EmbedFocusProc procedure, focusing on dead window} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete slave}
    ::_test_tmp::testInterp slave
    load {} Tktest slave
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    slave alias w1 winfo id .f1
    slave eval {
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        update
        after 200 {destroy .t1}
    }
    after 400
    focus -force .f1
    update
} -cleanup {
    interp delete slave
    interp delete child
    deleteWindows
} -result {}
test unixEmbed-5.3 {EmbedFocusProc procedure, FocusOut events} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
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
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







-
-
-
+
+
+



-
-
+
+









-
+


-
+

-
+







} -cleanup {
	deleteWindows
} -result {{{focus in .t1}} {{focus in .t1} {focus out .t1}}}
test unixEmbed-5.3a {EmbedFocusProc procedure, FocusOut events} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete slave}
    ::_test_tmp::testInterp slave
    load {} Tktest slave
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    slave alias w1 winfo id .f1
    slave eval {
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        set x {}
        bind .t1 <FocusIn> {lappend x "focus in %W"}
        bind .t1 <FocusOut> {lappend x "focus out %W"}
        update
    }
    focus -force .f1
    update
    set x [slave eval {update; set x }]
    set x [child eval {update; set x }]
    focus .
    update
    list $x [slave eval {update; set x}]
    list $x [child eval {update; set x}]
} -cleanup {
    interp delete slave
    interp delete child
    deleteWindows
} -result {{{focus in .t1}} {{focus in .t1} {focus out .t1}}}


test unixEmbed-6.1 {EmbedGeometryRequest procedure, window changes size} -constraints {
	unix notAqua
} -setup {
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
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







-
-
-
+
+
+



-
-
+
+










-
+







} -cleanup {
	deleteWindows
} -result {{{configure .t1 300 120}} 300x120+0+0}
test unixEmbed-6.1a {EmbedGeometryRequest procedure, window changes size} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete slave}
    ::_test_tmp::testInterp slave
    load {} Tktest slave
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    slave alias w1 winfo id .f1
    slave eval {
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        update
        bind .t1 <Configure> {set x {configure .t1 %w %h}}
        set x {}
        .t1 configure -width 300 -height 120
        update
        list $x [winfo geom .t1]
    }
} -cleanup {
    interp delete slave
    interp delete child
    deleteWindows
} -result {{configure .t1 300 120} 300x120+0+0}
test unixEmbed-6.2 {EmbedGeometryRequest procedure, window changes size} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
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
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







-
-
-
+
+
+




-
-
+
+










-
+







} -cleanup {
	deleteWindows
} -result {{{configure .t1 200 200}} 200x200+0+0}
test unixEmbed-6.2a {EmbedGeometryRequest procedure, window changes size} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete slave}
    ::_test_tmp::testInterp slave
    load {} Tktest slave
    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
    slave alias w1 winfo id .f1
    slave eval {
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        update
        bind .t1 <Configure> {set x {configure .t1 %w %h}}
	set x {}
        .t1 configure -width 300 -height 120
        update
        list $x [winfo geom .t1]
    }
} -cleanup {
    interp delete slave
    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
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
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







-
+











-
+


-
-
-
+
+
+




-
-
+
+






-
+









-
+







    focus -force .
    bind . <Key> {lappend x {key %A %E}}
    set x {}
    set y [dobg {
	    update
	    bind .t1 <Key> {lappend y {key %A}}
	    set y {}
	    event generate .t1 <Keys> -keysym a
	    event generate .t1 <Key> -keysym a
	    set y
    }]
    update
    list $x $y
} -cleanup {
	deleteWindows
    bind . <Key> {}
} -result {{{key a 1}} {}}
# TkpRedirectKeyEvent is not implemented in win or aqua.  If someone
# implements it they should change the constraints for this test.
test unixEmbed-7.1a {TkpRedirectKeyEvent procedure, forward keystroke} -constraints {
    unix notAqua
    unix notAqua failsOnXQuarz
} -setup {
    deleteWindows
    catch {interp delete slave}
    ::_test_tmp::testInterp slave
    load {} Tktest slave
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    deleteWindows
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    slave alias w1 winfo id .f1
    slave eval {
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
    }
    focus -force .
    bind . <Key> {lappend x {key %A %E}}
    set x {}
    set y [slave eval {
    set y [child eval {
        update
        bind .t1 <Key> {lappend y {key %A}}
        set y {}
        event generate .t1 <Key> -keysym a
        set y
    }]
    update
    list $x $y
} -cleanup {
    interp delete slave
    interp delete child
    deleteWindows
    bind . <Key> {}
} -result {{{key a 1}} {}}
test unixEmbed-7.2 {TkpRedirectKeyEvent procedure, don't forward keystroke width} -constraints {
	unix notAqua
} -setup {
	deleteWindows
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
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







-
-
-
+
+
+



-
-
+
+








-
+









-
+





-
+







	deleteWindows
    bind . <Key> {}
} -result {{} {{key b}}}
test unixEmbed-7.2a {TkpRedirectKeyEvent procedure, don't forward keystroke width} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete slave}
    ::_test_tmp::testInterp slave
    load {} Tktest slave
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    slave alias w1 winfo id .f1
    slave eval {
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
    }
    update
    focus -force .f1
    update
    bind . <Key> {lappend x {key %A}}
    set x {}
    set y [slave eval {
    set y [child eval {
        update
        bind .t1 <Key> {lappend y {key %A}}
        set y {}
        event generate .t1 <Key> -keysym b
        set y
    }]
    update
    list $x $y
} -cleanup {
    interp delete slave
    interp delete child
    deleteWindows
    bind . <Key> {}
} -result {{} {{key b}}}

test unixEmbed-8.1 {TkpClaimFocus procedure} -constraints {
    unix notAqua
    unix notAqua failsOnUbuntu failsOnXQuarz
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -width 200 -height 50
    pack .f1 .f2
    dobg "set w1 [winfo id .f1]"
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
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







-
-
-
+
+
+





-
-
+
+






-
+






-
+







	    lappend x [focus]
    }] [focus]
} -cleanup {
	deleteWindows
} -result {{{} .t1} .f1}
test unixEmbed-8.1a {TkpClaimFocus procedure} -constraints unix -setup {
    deleteWindows
    catch {interp delete slave}
    ::_test_tmp::testInterp slave
    load {} Tktest slave
    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
    slave alias w1 winfo id .f1
    slave eval {
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1] -highlightthickness 2 -bd 2 -relief sunken
    }
    # This should clear focus from the application embedded in .f1
    focus -force .f2
    update
    list [slave eval {
    list [child eval {
        set x [list [focus]]
        focus .t1
	update
        lappend x [focus]
    }] [focus]
} -cleanup {
    interp delete slave
    interp delete child
    deleteWindows
} -result {{{} .t1} .f1}
test unixEmbed-8.2 {TkpClaimFocus procedure} -constraints unix -setup {
    deleteWindows
    catch {interp delete child}
    interp create child
} -body {
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
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







-
+

-
+




















-
-
-
+
+
+



-
-
+
+








-
+





-
+

-
+


-

-
+

-
+

-
+





-
+

-
+



+

-
+

-
+






-
+

-
+













-
+

-
+







	    lappend x [testembed]
    }
    set x
} -cleanup {
	deleteWindows
} -result {{{XXX .f4 {} {}} {XXX .f3 {} {}} {XXX .f2 {} {}} {XXX .f1 {} {}}} {{XXX .f4 {} {}} {XXX .f2 {} {}} {XXX .f1 {} {}}} {{XXX .f2 {} {}} {XXX .f1 {} {}}} {{XXX .f2 {} {}}} {}}
test unixEmbed-9.2 {EmbedWindowDeleted procedure, check embeddedPtr} -constraints {
	unix testembed notAqua
    unix testembed 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 -highlightthickness 2 -bd 2 -relief sunken
	    set x {}
	    lappend x [testembed]
	    destroy .t1
	    lappend x [testembed]
    }
} -cleanup {
	deleteWindows
} -result {{{XXX {} {} .t1}} {}}
test unixEmbed-9.2a {EmbedWindowDeleted procedure, check embeddedPtr} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete slave}
    ::_test_tmp::testInterp slave
    load {} Tktest slave
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    slave alias w1 winfo id .f1
    slave eval {
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1] -highlightthickness 2 -bd 2 -relief sunken
        set x {}
        lappend x [testembed]
        destroy .t1
        lappend x [testembed]
    }
} -cleanup {
    interp delete slave
    interp delete child
    deleteWindows
} -result {{{XXX {} {} .t1}} {}}


test unixEmbed-10.1 {geometry propagation in tkUnixWm.c/UpdateGeometryInfo} -constraints {
	unix
    unix failsOnUbuntu failsOnXQuarz
} -setup {
	deleteWindows
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    update
    pack .f1
    update
    update idletasks
    toplevel .t1 -use [winfo id .f1] -width 150 -height 80
    update
    update idletasks
    wm geometry .t1 +40+50
    update
    update idletasks
    wm geometry .t1
} -cleanup {
	deleteWindows
} -result {150x80+0+0}
test unixEmbed-10.2 {geometry propagation in tkUnixWm.c/UpdateGeometryInfo} -constraints {
	unix
    unix failsOnUbuntu failsOnXQuarz
} -setup {
	deleteWindows
    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
    update idletasks
    wm geometry .t1 70x300+10+20
    update
    update idletasks
    wm geometry .t1
} -cleanup {
	deleteWindows
} -result {70x300+0+0}

test unixEmbed-11.1 {focus -force works for embedded toplevels} -constraints {
	unix
    unix
} -setup {
	deleteWindows
    deleteWindows
} -body {
    toplevel .t
    pack [frame .t.f -container 1 -width 200 -height 200] -fill both
    update idletasks
    toplevel .embed -use [winfo id .t.f] -bg green
    update idletasks
    focus -force .t
    focus -force .embed
    focus
} -cleanup {
    deleteWindows
} -result .embed
test unixEmbed-11.2 {mouse coordinates in embedded toplevels} -constraints {
	unix pressbutton
    unix pressbutton
} -setup {
	deleteWindows
    deleteWindows
} -body {
    toplevel .main
    set result {}
    pack [button .main.b -text "Main Button" \
	      -command {lappend result ".main.b"}] -padx 30 -pady 30
    pack [frame .main.f -container 1 -width 200 -height 200] -fill both
    update idletasks

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
1
2
3
4
5
6
7
8
9
10


11
12
13
14

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










-
-
+
+


-
+


+
+
+
+







# This file is a Tcl script to test out the procedures in tkUnixFont.c.
# It is organized in the standard fashion for Tcl tests.
#
# Many of these tests are visually oriented and cannot be checked
# programmatically (such as "does an underlined font appear to be
# underlined?"); these tests attempt to exercise the code in question,
# but there are no results that can be checked.  Some tests depend on the
# fonts having or not having certain properties, which may not be valid
# at all sites.
#
# Copyright (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.1
package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint failsOnUbuntuNoXft [expr {[testConstraint failsOnUbuntu] || (![catch {tk::pkgconfig get fontsystem} fs] && ($fs eq "xft"))}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

if {[tk windowingsystem] eq "x11"} {
    set xlsf [auto_execok xlsfonts]
}
foreach {constraint font} {
    hasArial	arial
    hasCourierNew	"courier new"
65
66
67
68
69
70
71
72

73
74

75
76
77
78
79
80
81

82
83
84
85
86
87
88

89
90
91
92
93
94
95

96
97
98
99
100
101
102
103
104
105

106
107
108
109
110
111

112
113
114

115
116
117

118
119

120
121
122
123
124
125
126
69
70
71
72
73
74
75

76
77

78
79
80
81
82
83
84

85
86
87
88
89
90
91

92
93
94
95
96
97
98

99
100
101
102
103
104
105
106
107
108

109
110
111
112
113
114

115
116
117

118
119
120

121
122

123
124
125
126
127
128
129
130







-
+

-
+






-
+






-
+






-
+









-
+





-
+


-
+


-
+

-
+







    update
    return "[winfo reqwidth .b.l] [winfo reqheight .b.l]"
}

test unixfont-1.1 {TkpGetNativeFont procedure: not native} {x11 noExceed} {
    list [catch {font measure {} xyz} msg] $msg
} {1 {font "" doesn't exist}}
test unixfont-1.2 {TkpGetNativeFont procedure: native} x11 {
test unixfont-1.2 {TkpGetNativeFont procedure: native} {x11 failsOnUbuntu} {
    font measure fixed 0
} {6}
} 6

test unixfont-2.1 {TkpGetFontFromAttributes procedure: no family} x11 {
    font actual {-size 10}
    set x {}
} {}
test unixfont-2.2 {TkpGetFontFromAttributes procedure: Times relatives} \
	{x11 noExceed hasTimesNew} {
	{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} {
	{x11 noExceed hasCourierNew failsOnUbuntu} {
    set x {}
    lappend x [lindex [font actual {-family "Courier New"}] 1]
    lappend x [lindex [font actual {-family "Monaco"}] 1]
    lappend x [lindex [font actual {-family "Courier"}] 1]
} {courier courier courier}
test unixfont-2.4 {TkpGetFontFromAttributes procedure: Helvetica relatives} \
	{x11 noExceed hasArial} {
	{x11 noExceed hasArial failsOnUbuntu} {
    set x {}
    lappend x [lindex [font actual {-family "Arial"}] 1]
    lappend x [lindex [font actual {-family "Geneva"}] 1]
    lappend x [lindex [font actual {-family "Helvetica"}] 1]
} {helvetica helvetica helvetica}
test unixfont-2.5 {TkpGetFontFromAttributes procedure: fallback} x11 {
    font actual {-xyz-xyz-*-*-*-*-*-*-*-*-*-*-*-*}
    set x {}
} {}
test unixfont-2.6 {TkpGetFontFromAttributes: fallback to fixed family} x11 {
test unixfont-2.6 {TkpGetFontFromAttributes: fallback to fixed family} {x11 failsOnUbuntu} {
    lindex [font actual {-family fixed -size 10}] 1
} {fixed}
test unixfont-2.7 {TkpGetFontFromAttributes: fixed family not available!} x11 {
    # no test available
} {}
test unixfont-2.8 {TkpGetFontFromAttributes: loop over returned font names} x11 {
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} {
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 {
test unixfont-2.10 {TkpGetFontFromAttributes: scalable font found} {x11 failsOnUbuntuNoXft} {
    lindex [font actual {-family courier -size 37}] 3
} {37}
} 37
test unixfont-2.11 {TkpGetFontFromAttributes: font cannot be loaded} x11 {
    # On Linux, XListFonts() was returning names for fonts that do not
    # actually exist, causing the subsequent XLoadQueryFont() to fail
    # unexpectedly.  Now falls back to another font if that happens.

    font actual {-size 14}
    set x {}
162
163
164
165
166
167
168
169

170
171
172
173

174
175
176
177

178
179
180
181
182
183
184
185
186
187
188
189

190
191
192
193
194
195
196
166
167
168
169
170
171
172

173
174
175
176

177
178
179
180

181
182
183
184
185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
200







-
+



-
+



-
+











-
+







    .b.l config -text "000000 00000"
    getsize
} "[expr $ax*6] [expr $ay*2]"
test unixfont-5.7 {Tk_MeasureChars procedure: already saw space in line} x11 {
    .b.l config -text "000000     00000"
    getsize
} "[expr $ax*6] [expr $ay*2]"
test unixfont-5.8 {Tk_MeasureChars procedure: internal spaces significant} x11 {
test unixfont-5.8 {Tk_MeasureChars procedure: internal spaces significant} {x11 failsOnUbuntu} {
    .b.l config -text "00  000     00000"
    getsize
} "[expr $ax*7] [expr $ay*2]"
test unixfont-5.9 {Tk_MeasureChars procedure: TK_PARTIAL_OK} x11 {
test unixfont-5.9 {Tk_MeasureChars procedure: TK_PARTIAL_OK} {x11 failsOnUbuntu} {
    .b.c dchars $t 0 end
    .b.c insert $t 0 "0000"
    .b.c index $t @[expr int($ax*2.5)],1
} {2}
} 2
test unixfont-5.10 {Tk_MeasureChars procedure: TK_AT_LEAST_ONE} x11 {
    .b.l config -text "000000000000"
    getsize
} "[expr $ax*10] [expr $ay*2]"
test unixfont-5.11 {Tk_MeasureChars: TK_AT_LEAST_ONE + not even one char fit!} x11 {
    set a [.b.l cget -wrap]
    .b.l config -text "000000" -wrap 1
    set x [getsize]
    .b.l config -wrap $a
    set x
} "$ax [expr $ay*6]"
test unixfont-5.12 {Tk_MeasureChars procedure: include eol spaces} x11 {
test unixfont-5.12 {Tk_MeasureChars procedure: include eol spaces} {x11 failsOnUbuntu} {
    .b.l config -text "000   \n000"
    getsize
} "[expr $ax*6] [expr $ay*2]"

test unixfont-6.1 {Tk_DrawChars procedure: loop test} x11 {
    .b.l config -text "a"
    update
239
240
241
242
243
244
245
246

247
248
249
250
251
252
253
254
255
256

257
258

259
260
261
262
263
264
265
266
267


268
269
270
271
272
273
274
243
244
245
246
247
248
249

250
251
252
253
254
255
256
257
258
259

260
261

262
263
264
265
266
267
268
269


270
271
272
273
274
275
276
277
278







-
+









-
+

-
+







-
-
+
+







    font configure xyz -family times
    update
    destroy .c
    font delete xyz
} {}
test unixfont-8.2 {AllocFont procedure: parse information from XLFD} x11 {
    expr {[lindex [font actual {-family times -size 0}] 3] == 0}
} {0}
} 0
test unixfont-8.3 {AllocFont procedure: can't parse info from name} x11 {
    catch {unset fontArray}
    # check that font actual returns the correct attributes.
    # the values of those attributes are system dependent.
    array set fontArray [font actual a12biluc]
    set result [lsort [array names fontArray]]
    catch {unset fontArray}
    set result
} {-family -overstrike -size -slant -underline -weight}
test unixfont-8.4 {AllocFont procedure: classify characters} x11 {
test unixfont-8.4 {AllocFont procedure: classify characters} {x11 failsOnUbuntu failsOnXQuarz} {
    set x 0
    incr x [font measure $courier "\u4000"]   ;# 6
    incr x [font measure $courier "䀀"]   ;# 6
    incr x [font measure $courier "\002"]   ;# 4
    incr x [font measure $courier "\012"]   ;# 2
    incr x [font measure $courier "\101"]   ;# 1
    set x
} [expr $cx*13]
test unixfont-8.5 {AllocFont procedure: setup widths of normal chars} x11 {
    font metrics $courier -fixed
} {1}
test unixfont-8.6 {AllocFont procedure: setup widths of special chars} x11 {
} 1
test unixfont-8.6 {AllocFont procedure: setup widths of special chars} {x11 failsOnUbuntu failsOnXQuarz} {
    set x 0
    incr x [font measure $courier "\001"]   ;# 4
    incr x [font measure $courier "\002"]   ;# 4
    incr x [font measure $courier "\012"]   ;# 2
    set x
} [expr $cx*10]
test unixfont-8.7 {AllocFont procedure: XA_UNDERLINE_POSITION} x11 {
288
289
290
291
292
293
294
295

296
297
298
299
300
301
302
303
304

305
306
307
308
309
310
311
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306
307

308
309
310
311
312
313
314
315







-
+








-
+







    set x {}
} {}
test unixfont-8.11 {AllocFont procedure: XA_UNDERLINE_POSITION was 0} x11 {
    catch {font actual -adobe-courier-bold-i-normal--0-0-0-0-m-0-iso8859-1}
    set x {}
} {}

test unixfont-9.1 {GetControlCharSubst procedure: 2 chars subst} x11 {
test unixfont-9.1 {GetControlCharSubst procedure: 2 chars subst} {x11 failsOnUbuntu failsOnXQuarz} {
    .b.c dchars $t 0 end
    .b.c insert $t 0 "0\a0"
    set x {}
    lappend x [.b.c index $t @[expr $ax*0],0]
    lappend x [.b.c index $t @[expr $ax*1],0]
    lappend x [.b.c index $t @[expr $ax*2],0]
    lappend x [.b.c index $t @[expr $ax*3],0]
} {0 1 1 2}
test unixfont-9.2 {GetControlCharSubst procedure: 4 chars subst} x11 {
test unixfont-9.2 {GetControlCharSubst procedure: 4 chars subst} {x11 failsOnUbuntu failsOnXQuarz} {
    .b.c dchars $t 0 end
    .b.c insert $t 0 "0\0010"
    set x {}
    lappend x [.b.c index $t @[expr $ax*0],0]
    lappend x [.b.c index $t @[expr $ax*1],0]
    lappend x [.b.c index $t @[expr $ax*2],0]
    lappend x [.b.c index $t @[expr $ax*3],0]

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 (c) 1995-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1995-1996 Sun Microsystems, Inc.
# Copyright © 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
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







# This file contains tests for the tkUnixSelect.c file.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1999 by Scriptics Corporation.
# Copyright © 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
111
112
113
114
115
116
117
118

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

135
136
137
138
139
140

141
142
143
144
145
146
147
148
149
150
151

152
153
154
155

156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175

176
177
178
179
180

181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197

198
199
200
201

202
203
204
205
206
207
208
209
210
211
212
213
214

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

230
231
232
233
234
235

236
237
238
239
240
241
242
243
244
245

246
247
248
249
250
251

252
253
254
255
256
257
258
259
260
261

262
263
264
265
266
267

268
269
270
271
272
273
274
275
276
277
278
279
280

281
282
283
284
285
286

287
288
289
290
291
292
293
294
295
296

297
298
299
300
301
302

303
304
305
306
307
308
309
310
311
312

313
314
315
316
317
318

319
320
321
322
323
324
325
326
327
328

329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344

345
346
347
348
349
350

351
352
353
354
355
356
357
358
359
360

361
362
363
364
365
366

367
368
369
370
371
372
373
374
375
376

377
378
379
380
381
382

383
384
385
386
387
388
389
390
391
392

393
394
395
396
397
398
399
400

401
402
403
404
405
406
407
408
409
410

411
412
413
414
415
416
417
418

419
420
421
422
423
424
425
111
112
113
114
115
116
117

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

134
135
136
137
138
139

140
141
142
143
144
145
146
147
148
149
150

151
152
153
154

155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174

175
176
177
178
179

180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196

197
198
199
200

201
202
203
204
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
226
227
228

229
230
231
232
233
234

235
236
237
238
239
240
241
242
243
244

245
246
247
248
249
250

251
252
253
254
255
256
257
258
259
260

261
262
263
264
265
266

267
268
269
270
271
272
273
274
275
276
277
278
279

280
281
282
283
284
285

286
287
288
289
290
291
292
293
294
295

296
297
298
299
300
301

302
303
304
305
306
307
308
309
310
311

312
313
314
315
316
317

318
319
320
321
322
323
324
325
326
327

328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343

344
345
346
347
348
349

350
351
352
353
354
355
356
357
358
359

360
361
362
363
364
365

366
367
368
369
370
371
372
373
374
375

376
377
378
379
380
381

382
383
384
385
386
387
388
389
390
391

392
393
394
395
396
397
398
399

400
401
402
403
404
405
406
407
408
409

410
411
412
413
414
415
416
417

418
419
420
421
422
423
424
425







-
+















-
+





-
+










-
+



-
+



















-
+




-
+
















-
+



-
+












-
+














-
+





-
+









-
+





-
+









-
+





-
+












-
+





-
+









-
+





-
+









-
+





-
+









-
+















-
+





-
+









-
+





-
+









-
+





-
+









-
+







-
+









-
+







-
+







    x11
} -setup {
    destroy .e
    setupbg
} -body {
    pack [entry .e]
    update
    .e insert 0 \u00fcber
    .e insert 0 über
    .e selection range 0 end
    dobg {string length [selection get]}
} -cleanup {
    cleanupbg
    destroy .e
} -result 4

test unixSelect-1.2 {TkSelGetSelection procedure: simple i18n text, iso8859-1} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 \u00fc\u0444
        .e insert 0 üф
        .e selection range 0 end
    }
    selection get
} -cleanup {
    cleanupbg
} -result \u00fc?
} -result ü?

test unixSelect-1.3 {TkSelGetSelection procedure: simple i18n text, iso2022} -constraints {
    x11
} -setup {
    setupbg
    setup
} -body {
    selection handle -type COMPOUND_TEXT -format COMPOUND_TEXT . \
        {handler COMPOUND_TEXT}
    selection own .
    set selValue \u00fc\u0444
    set selValue üф
    set selInfo {}
    set result [dobg {
        set x [selection get -type COMPOUND_TEXT]
        list [string equal \u00fc\u0444 $x] [string length $x]
        list [string equal üф $x] [string length $x]
    }]
    lappend result $selInfo
} -cleanup {
    cleanupbg
} -result {1 2 {COMPOUND_TEXT 0 4000}}

test unixSelect-1.4 {TkSelGetSelection procedure: INCR i18n text, iso2022} -constraints {
    x11
} -setup {
    setupbg
    setup
} -body {
    # This test is subtle.  The selection ends up getting fetched twice by
    # Tk:  once to compute the length, and again to actually send the data.
    # The first time through, we don't convert the data to ISO2022, so the
    # buffer boundaries end up being different in the two passes.
    selection handle -type COMPOUND_TEXT -format COMPOUND_TEXT . \
        {handler COMPOUND_TEXT}
    selection own .
    set selValue [string repeat x 3999]\u00fc\u0444[string repeat x 3999]
    set selValue [string repeat x 3999]üф[string repeat x 3999]
    set selInfo {}
    set result [dobg {
        set x [selection get -type COMPOUND_TEXT]
        list [string equal \
            [string repeat x 3999]\u00fc\u0444[string repeat x 3999] $x] \
            [string repeat x 3999]üф[string repeat x 3999] $x] \
            [string length $x]
    }]
    lappend result $selInfo
} -cleanup {
    cleanupbg
} -result {1 8000 {COMPOUND_TEXT 0 4000 COMPOUND_TEXT 4000 3999 COMPOUND_TEXT 7998 4000 COMPOUND_TEXT 0 4000 COMPOUND_TEXT 4000 3998 COMPOUND_TEXT 7997 4000}}

test unixSelect-1.5 {TkSelGetSelection procedure: simple i18n text, iso2022} -constraints {
    x11
} -setup {
    setupbg
    setup
} -body {
    selection handle -type COMPOUND_TEXT -format COMPOUND_TEXT . \
        {handler COMPOUND_TEXT}
    selection own .
    set selValue \u00fc\u0444
    set selValue üф
    set selInfo {}
    set result [dobg {
        set x [selection get -type COMPOUND_TEXT]
        list [string equal \u00fc\u0444 $x] [string length $x]
        list [string equal üф $x] [string length $x]
    }]
    lappend result $selInfo
} -cleanup {
    cleanupbg
} -result {1 2 {COMPOUND_TEXT 0 4000}}

test unixSelect-1.6 {TkSelGetSelection procedure: INCR i18n text} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg [subst -nobackslashes {entry .e; pack .e; update
    .e insert 0 \u00fcber$longValue
    .e insert 0 über$longValue
    .e selection range 0 end}]
    string length [selection get]
} -cleanup {
    cleanupbg
} -result [expr {4 + [string length $longValue]}]

test unixSelect-1.7 {TkSelGetSelection procedure: INCR i18n text} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 [string repeat x 3999]\u00fc
        .e insert 0 [string repeat x 3999]ü
        .e selection range 0 end
    }
    selection get
} -cleanup {
    cleanupbg
} -result [string repeat x 3999]\u00fc
} -result [string repeat x 3999]ü

test unixSelect-1.8 {TkSelGetSelection procedure: INCR i18n text} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 \u00fc[string repeat x 3999]
        .e insert 0 ü[string repeat x 3999]
        .e selection range 0 end
    }
    selection get
} -cleanup {
    cleanupbg
} -result \u00fc[string repeat x 3999]
} -result ü[string repeat x 3999]

test unixSelect-1.9 {TkSelGetSelection procedure: INCR i18n text} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 [string repeat x 3999]\u00fc[string repeat x 4000]
        .e insert 0 [string repeat x 3999]ü[string repeat x 4000]
        .e selection range 0 end
    }
    selection get
} -cleanup {
    cleanupbg
} -result [string repeat x 3999]\u00fc[string repeat x 4000]
} -result [string repeat x 3999]ü[string repeat x 4000]
# Now some tests to make sure that the right thing is done when
# transferring UTF8 selections, to prevent [Bug 614650] and its ilk
# from rearing its ugly head again.

test unixSelect-1.10 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 [string repeat x 3999]\u00fc
        .e insert 0 [string repeat x 3999]ü
        .e selection range 0 end
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result [string repeat x 3999]\u00fc
} -result [string repeat x 3999]ü

test unixSelect-1.11 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 \u00fc[string repeat x 3999]
        .e insert 0 ü[string repeat x 3999]
        .e selection range 0 end
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result \u00fc[string repeat x 3999]
} -result ü[string repeat x 3999]

test unixSelect-1.12 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 [string repeat x 3999]\u00fc[string repeat x 4000]
        .e insert 0 [string repeat x 3999]ü[string repeat x 4000]
        .e selection range 0 end
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result [string repeat x 3999]\u00fc[string repeat x 4000]
} -result [string repeat x 3999]ü[string repeat x 4000]

test unixSelect-1.13 {TkSelGetSelection procedure: simple i18n text, utf-8} -constraints {
    x11
} -setup {
    destroy .e
    setupbg
} -body {
    pack [entry .e]
    update
    .e insert 0 \u00fcber\u0444
    .e insert 0 überф
    .e selection range 0 end
    dobg {string length [selection get -type UTF8_STRING]}
} -cleanup {
    destroy .e
    cleanupbg
} -result 5

test unixSelect-1.14 {TkSelGetSelection procedure: simple i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 \u00fc\u0444
        .e insert 0 üф
        .e selection range 0 end
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result \u00fc\u0444
} -result üф

test unixSelect-1.15 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 [string repeat [string repeat \u00c4\u00e4 50]\n 21]
        .e insert 0 [string repeat [string repeat Ää 50]\n 21]
        .e selection range 0 end
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result [string repeat [string repeat \u00c4\u00e4 50]\n 21]
} -result [string repeat [string repeat Ää 50]\n 21]

test unixSelect-1.16 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 i[string repeat [string repeat \u00c4\u00e4 50]\n 21]
        .e insert 0 i[string repeat [string repeat Ää 50]\n 21]
        .e selection range 0 end
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result i[string repeat [string repeat \u00c4\u00e4 50]\n 21]
} -result i[string repeat [string repeat Ää 50]\n 21]

test unixSelect-1.17 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [text .t]
        update
        .t insert 1.0 [string repeat [string repeat \u00c4\u00e4 50]\n 21]
        .t insert 1.0 [string repeat [string repeat Ää 50]\n 21]
        # Has to be selected in a separate stage
        .t tag add sel 1.0 21.end+1c
    }
    after 10
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result [string repeat [string repeat \u00c4\u00e4 50]\n 21]
} -result [string repeat [string repeat Ää 50]\n 21]

test unixSelect-1.18 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [text .t]
        update
        .t insert 1.0 i[string repeat [string repeat \u00c4\u00e4 50]\n 21]
        .t insert 1.0 i[string repeat [string repeat Ää 50]\n 21]
        # Has to be selected in a separate stage
        .t tag add sel 1.0 21.end+1c
    }
    after 10
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result i[string repeat [string repeat \u00c4\u00e4 50]\n 21]
} -result i[string repeat [string repeat Ää 50]\n 21]

test unixSelect-1.19 {Automatic UTF8_STRING support for selection handle} -constraints {
    unix
} -setup {
    destroy .l
} -body {
    # See Bug #666346 "Selection handling crashes under KDE 3.0"

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
61
62
63
64
65
66
1
2
3
4



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










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



43
44
45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60




-
-
-
+
+
+








+
+
+






-
-
-
-
-
-
-
-
-
-

















+
-
-
-
+
+
+







-
+







# This file is a Tcl script to test out Tk's interactions with
# the window manager, including the "wm" command.  It is organized
# in the standard fashion for Tcl tests.
#
# Copyright (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 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(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

proc sleep ms {
    global x
    after $ms {set x 1}
    vwait x
}

# The macOS window manager shows an animation when a window is deiconified.
# Tests which check the geometry of a window after deiconifying it should
# wait for the animation to finish.

 proc animationDelay {} {
    if {[tk windowingsystem] == "aqua"} {
    sleep 250
    }
 }

# Procedure to set up a collection of top-level windows

proc makeToplevels {} {
    deleteWindows
    foreach i {.raise1 .raise2 .raise3} {
	toplevel $i
	wm geom $i 150x100+0+0
	update
    }
}

# On macOS windows are not allowed to overlap the menubar at the top
# of the screen.  So tests which move a window and then check whether
# it got moved to the requested location should use a y coordinate
# larger than the height of the menubar (normally 23 pixels).

if {[tk windowingsystem] eq "aqua"} {
    set mb [expr [menubarheight] + 1]
    set Y0 23
    set Y2 25
    set Y5 28
    set Y0 $mb
    set Y2 [expr $mb + 2]
    set Y5 [expr $mb + 5]
} else {
    set Y0 0
    set Y2 2
    set Y5 5
}

set i 1
foreach geom "+23+80 +80+23 +0+$Y0" {
foreach geom "+$Y0+80 +80+$Y0 +0+$Y0" {
    destroy .t
    test unixWm-1.$i {initial window position} unix {
	toplevel .t -width 200 -height 150
	wm geom .t $geom
	update
	wm geom .t
    } 200x150$geom
78
79
80
81
82
83
84
85

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

98
99
100

101
102

103
104

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

117
118

119
120

121
122
123
124
125
126
127
72
73
74
75
76
77
78

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

91
92
93

94
95

96
97

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

110
111

112
113

114
115
116
117
118
119
120
121







-
+











-
+


-
+

-
+

-
+











-
+

-
+

-
+







wm geom .t +200+200
update
wm geom .t +150+150
update
scan [wm geom .t] %dx%d+%d+%d width height x y
set xerr [expr 150-$x]
set yerr [expr 150-$y]
foreach geom "+20+80 +80+23 +0+$Y0 -0-0 +0-0 -0+$Y0 -10-5 -10+$Y5 +10-5" {
foreach geom "+20+80 +80+$Y0 +0+$Y0 -0-0 +0-0 -0+$Y0 -10-5 -10+$Y5 +10-5" {
    test unixWm-2.$i {moving window while mapped} unix {
	wm geom .t $geom
	update
	scan [wm geom .t] %dx%d%1s%d%1s%d width height xsign x ysign y
	format "%s%d%s%d" $xsign [eval expr $x$xsign$xerr] $ysign \
		[eval expr $y$ysign$yerr]
    } $geom
    incr i
}

set i 1
foreach geom "+20+80 +80+23 +0+$Y0 -0-0 +0-0 -0+$Y0 -10-5 -10+$Y5 +10-5" {
foreach geom "+20+80 +80+$Y0 +0+$Y0 -0-0 +0-0 -0+$Y0 -10-5 -10+$Y5 +10-5" {
    test unixWm-3.$i {moving window while iconified} unix {
	wm iconify .t
	sleep 200
	update idletasks
	wm geom .t $geom
	update
	update idletasks
	wm deiconify .t
	animationDelay
	update idletasks
	scan [wm geom .t] %dx%d%1s%d%1s%d width height xsign x ysign y
	format "%s%d%s%d" $xsign [eval expr $x$xsign$xerr] $ysign \
		[eval expr $y$ysign$yerr]
    } $geom
    incr i
}

set i 1
foreach geom "+20+80 +100+40 +0+$Y0" {
    test unixWm-4.$i {moving window while withdrawn} unix {
	wm withdraw .t
	sleep 200
	update idletasks
	wm geom .t $geom
	update
	update idletasks
	wm deiconify .t
	animationDelay
	update idletasks
	wm geom .t
    } 100x150$geom
    incr i
}

test unixWm-5.1 {compounded state changes} {unix nonPortable} {
    destroy .t
190
191
192
193
194
195
196
197

198
199
200
201
202
203
204

205
206
207
208
209
210

211
212
213
214
215
216
217

218
219
220
221
222
223
224
184
185
186
187
188
189
190

191
192
193
194
195
196
197

198
199
200
201
202
203

204
205
206
207
208
209
210

211
212
213
214
215
216
217
218







-
+






-
+





-
+






-
+







    wm withdraw .t
    wm iconify .t
    list [winfo ismapped .t] [wm state .t]
} {0 iconic}

destroy .t
toplevel .t -width 200 -height 100
wm geom .t +10+23
wm geom .t +10+$Y0
wm minsize .t 1 1
update
test unixWm-6.1 {size changes} unix {
    .t config -width 180 -height 150
    update
    wm geom .t
} 180x150+10+23
} 180x150+10+$Y0
test unixWm-6.2 {size changes} unix {
    wm geom .t 250x60
    .t config -width 170 -height 140
    update
    wm geom .t
} 250x60+10+23
} 250x60+10+$Y0
test unixWm-6.3 {size changes} unix {
    wm geom .t 250x60
    .t config -width 170 -height 140
    wm geom .t {}
    update
    wm geom .t
} 170x140+10+23
} 170x140+10+$Y0
test unixWm-6.4 {size changes} {unix nonPortable userInteraction} {
    wm minsize .t 1 1
    update
    puts stdout "Please resize window \"t\" with the mouse (but don't move it!),"
    puts -nonewline stdout "then hit return: "
    flush stdout
    gets stdin
292
293
294
295
296
297
298
299

300
301
302
303

304
305
306
307
308
309
310
311
312
313

314
315
316
317
318
319
320
286
287
288
289
290
291
292

293
294
295
296
297
298
299
300
301
302
303
304
305
306
307

308
309
310
311
312
313
314
315







-
+




+









-
+







    list [catch {wm iconwindow} msg] $msg
} {1 {wrong # args: should be "wm option window ?arg ...?"}}
test unixWm-8.3 {icon windows} unix {
    destroy .t
    toplevel .t -width 100 -height 30
    list [catch {wm iconwindow .t b c} msg] $msg
} {1 {wrong # args: should be "wm iconwindow window ?pathName?"}}
test unixWm-8.4 {icon windows} unix {
test unixWm-8.4 {icon windows} {unix failsOnUbuntu} {
    destroy .t
    destroy .icon
    toplevel .t -width 100 -height 30
    wm geom .t +0+0
    update idletasks
    set result [wm iconwindow .t]
    toplevel .icon -width 50 -height 50 -bg red
    wm iconwindow .t .icon
    lappend result [wm iconwindow .t] [wm state .icon]
    wm iconwindow .t {}
    lappend result [wm iconwindow .t] [wm state .icon]
    update
    lappend result [winfo ismapped .t] [winfo ismapped .icon]
    wm iconify .t
    update
    update idletasks
    lappend result [winfo ismapped .t] [winfo ismapped .icon]
} {.icon icon {} withdrawn 1 0 0 0}
test unixWm-8.5 {icon windows} unix {
    destroy .t
    toplevel .t -width 100 -height 30
    list [catch {wm iconwindow .t .gorp} msg] $msg
} {1 {bad window path name ".gorp"}}
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
339
340
341
342
343
344
345

346
347
348
349
350
351
352







-







    wm geom .icon +0+0
    update
    set result [winfo ismapped .icon]
    toplevel .t -width 100 -height 30
    wm geom .t +0+0
    tkwait visibility .t	;# Needed to keep tvtwm happy.
    wm iconwindow .t .icon
    sleep 500
    lappend result [winfo ismapped .t] [winfo ismapped .icon]
} {1 1 0}
test unixWm-8.9 {icon windows} {unix nonPortable} {
    # This test is non-portable because some window managers will
    # destroy an icon window when it's associated window is destroyed.

    destroy .t
416
417
418
419
420
421
422
423
424
425

426
427
428
429
430
431
432
433
434

435
436
437
438
439
440
441

442
443
444
445
446
447
448
410
411
412
413
414
415
416

417

418
419
420

421
422
423
424
425

426
427
428
429
430
431
432

433
434
435
436
437
438
439
440







-

-
+


-





-
+






-
+







command
}
test unixWm-9.3 {TkWmMapWindow procedure, iconic windows} unix {
    destroy .t
    toplevel .t -width 100 -height 300 -bg blue
    wm geom .t +0+0
    wm iconify .t
    sleep 500
    winfo ismapped .t
} {0}
} 0
test unixWm-9.4 {TkWmMapWindow procedure, icon windows} unix {
    destroy .t
    sleep 500
    toplevel .t -width 100 -height 50 -bg blue
    tkwait visibility .t
    wm iconwindow . .t
    update
    set result [winfo ismapped .t]
} {0}
} 0
test unixWm-9.5 {TkWmMapWindow procedure, normal windows} unix {
    destroy .t
    toplevel .t -width 200 -height 20
    wm geom .t +0+0
    update
    winfo ismapped .t
} {1}
} 1

test unixWm-10.1 {TkWmDeadWindow procedure, canceling UpdateGeometry idle handler} unix {
    destroy .t
    toplevel .t -width 100 -height 50
    wm geom .t +0+0
    update
    .t configure -width 200 -height 100
639
640
641
642
643
644
645
646

647
648
649
650
651
652
653
631
632
633
634
635
636
637

638
639
640
641
642
643
644
645







-
+







    destroy .icon
    toplevel .icon -width 50 -height 50 -bg red
    wm iconwindow .t .icon
    set result [list [catch {wm deiconify .icon} msg] $msg]
    destroy .icon
    set result
} {1 {can't deiconify .icon: it is an icon for .t}}
test unixWm-16.3 {Tk_WmCmd procedure, "deiconify" option} unix {
test unixWm-16.3 {Tk_WmCmd procedure, "deiconify" option} {unix failsOnUbuntu} {
    wm iconify .t
    set result {}
    lappend result [winfo ismapped .t] [wm state .t]
    wm deiconify .t
    lappend result [winfo ismapped .t] [wm state .t]
} {0 iconic 1 normal}

668
669
670
671
672
673
674
675

676
677
678
679
680
681
682
683
684
685

686
687
688
689
690
691
692
660
661
662
663
664
665
666

667
668
669
670
671
672
673
674
675
676

677
678
679
680
681
682
683
684







-
+









-
+







} {passive active passive}

test unixWm-18.1 {Tk_WmCmd procedure, "frame" option} unix {
    list [catch {wm frame .t 12} msg] $msg
} {1 {wrong # args: should be "wm frame window"}}
test unixWm-18.2 {Tk_WmCmd procedure, "frame" option} {unix nonPortable} {
    expr [wm frame .t] == [winfo id .t]
} {0}
} 0
test unixWm-18.3 {Tk_WmCmd procedure, "frame" option} {unix nonPortable} {
    destroy .t2
    toplevel .t2
    wm geom .t2 +0+0
    wm overrideredirect .t2 1
    update
    set result [expr [wm frame .t2] == [winfo id .t2]]
    destroy .t2
    set result
} {1}
} 1

test unixWm-19.1 {Tk_WmCmd procedure, "geometry" option} unix {
    list [catch {wm geometry .t 12 13} msg] $msg
} {1 {wrong # args: should be "wm geometry window ?newGeometry?"}}
test unixWm-19.2 {Tk_WmCmd procedure, "geometry" option} {unix nonPortable} {
    wm geometry .t -1+5
    update
789
790
791
792
793
794
795
796

797
798
799
800
801
802
803
781
782
783
784
785
786
787

788
789
790
791
792
793
794
795







-
+







    toplevel .t2
    wm geom .t2 +0+0
    wm group .t .t2
    set hints [testprop [testwrapper .t] WM_HINTS]
    set result [expr [testwrapper .t2] - [lindex $hints 8]]
    destroy .t2
    set result
} {0}
} 0
test unixWm-21.5 {Tk_WmCmd procedure, "group" option, create leader wrapper} {unix testwrapper} {
    destroy .t2
    destroy .t3
    toplevel .t2 -width 120 -height 300
    wm geometry .t2 +0+0
    toplevel .t3 -width 120 -height 300
    wm geometry .t2 +0+0
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
849
850
851
852
853
854
855


856
857
858
859
860

861
862

863
864
865
866


867
868
869
870
871

872
873
874

875
876
877
878
879
880
881
882







-
-
+
+



-
+

-
+



-
-
+
+



-
+


-
+







    destroy .t2
    toplevel .t2
    wm geom .t2 +0+0
    wm iconwindow .t .t2
    set result [list [catch {wm iconify .t2} msg] $msg]
    destroy .t2
    set result
} {1 {can't iconify .t2: it is an icon for .t}}
test unixWm-23.5 {Tk_WmCmd procedure, "iconify" option} unix {
} {1 {can't iconify ".t2": it is an icon for ".t"}}
test unixWm-23.5 {Tk_WmCmd procedure, "iconify" option} {unix failsOnUbuntu} {
    destroy .t2
    toplevel .t2
    wm geom .t2 +0+0
    update
    update idletasks
    wm iconify .t2
    update
    update idletasks
    set result [winfo ismapped .t2]
    destroy .t2
    set result
} {0}
test unixWm-23.6 {Tk_WmCmd procedure, "iconify" option} unix {
} 0
test unixWm-23.6 {Tk_WmCmd procedure, "iconify" option} {unix failsOnUbuntu} {
    destroy .t2
    toplevel .t2
    wm geom .t2 -0+0
    update
    update idletasks
    set result [winfo ismapped .t2]
    wm iconify .t2
    update
    update idletasks
    lappend result [winfo ismapped .t2]
    destroy .t2
    set result
} {1 0}

test unixWm-24.1 {Tk_WmCmd procedure, "iconmask" option} unix {
    list [catch {wm iconmask .t 12 13} msg] $msg
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
1297
1298
1299
1300
1301
1302
1303

1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314

1315
1316
1317
1318
1319
1320
1321
1322







-
+










-
+







    lappend result [wm transient .t2] [expr [testwrapper .t] - $transient]
    wm transient .t2 {}
    lappend result [wm transient .t2] \
	    [testprop [testwrapper .t2] WM_TRANSIENT_FOR]
    destroy .t2
    set result
} {{} {} .t 0 {} {}}
test unixWm-37.4 {TkWmDeadWindow, destroy on master should clear transient} {unix testwrapper} {
test unixWm-37.4 {TkWmDeadWindow, destroy on toplevel should clear transient} {unix testwrapper} {
    destroy .t2
    toplevel .t2
    destroy .t3
    toplevel .t3
    wm transient .t2 .t3
    update
    destroy .t3
    update
    list [wm transient .t2] [testprop [testwrapper .t2] WM_TRANSIENT_FOR]
} {{} {}}
test unixWm-37.5 {Tk_WmCmd procedure, "transient" option, create master wrapper} {unix testwrapper} {
test unixWm-37.5 {Tk_WmCmd procedure, "transient" option, create toplevel wrapper} {unix testwrapper} {
    destroy .t2
    destroy .t3
    toplevel .t2 -width 120 -height 300
    wm geometry .t2 +0+0
    toplevel .t3 -width 120 -height 300
    wm geometry .t2 +0+0
    set result [list [testwrapper .t2]]
1380
1381
1382
1383
1384
1385
1386
1387
1388


1389
1390
1391
1392

1393
1394
1395
1396
1397
1398
1399
1372
1373
1374
1375
1376
1377
1378

1379
1380
1381
1382
1383
1384

1385
1386
1387
1388
1389
1390
1391
1392







-

+
+



-
+







    update
    wm geometry .t
} "20x20+0+$Y0"

test unixWm-41.1 {ConfigureEvent procedure, internally generated size changes} unix {
    destroy .t
    toplevel .t -width 400 -height 150
    wm geometry .t +0+0
    tkwait visibility .t
    wm geometry .t +0+0
    update idletasks
    set result {}
    lappend result [winfo width .t] [winfo height .t]
    .t configure -width 200 -height 300
    sleep 500
    update idletasks
    lappend result [winfo width .t] [winfo height .t]
} {400 150 200 300}
test unixWm-41.2 {ConfigureEvent procedure, menubars} {nonPortable testmenubar} {
    destroy .t
    toplevel .t -width 300 -height 200 -bd 2 -relief raised
    wm geom .t +0+0
    update
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
1432
1433
1434
1435
1436
1437
1438

1439
1440
1441
1442
1443
1444
1445
1446
1447
1448

1449
1450
1451
1452

1453
1454
1455
1456
1457
1458
1459
1460







-
+









-
+



-
+







    update
    set result
} {configured: 130 200}

# No tests for ReparentEvent or ComputeReparentGeometry; I can't figure
# out how to exercise these procedures reliably.

test unixWm-42.1 {WrapperEventProc procedure, map and unmap events} unix {
test unixWm-42.1 {WrapperEventProc procedure, map and unmap events} {unix failsOnUbuntu} {
    destroy .t
    toplevel .t -width 400 -height 150
    wm geometry .t +0+0
    tkwait visibility .t
    set result {}
    bind .t <Map> {set x "mapped"}
    bind .t <Unmap> {set x "unmapped"}
    set x {no event}
    wm iconify .t
    animationDelay
    update idletasks
    lappend result $x [winfo ismapped .t]
    set x {no event}
    wm deiconify .t
    animationDelay
    update idletasks
    lappend result $x [winfo ismapped .t]
} {unmapped 0 mapped 1}

test unixWm-43.1 {TopLevelReqProc procedure, embedded in same process} unix {
    destroy .t
    toplevel .t -width 200 -height 200
    wm geom .t +0+0
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
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







-
+









-
+







    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 {
test unixWm-44.7 {UpdateGeometryInfo procedure, computing position} {unix failsOnXQuarz} {
    tkwait visibility .t
    wm overrideredirect .t 1
    update
    wm geometry .t +5-10
    update
    list [winfo x .t] [winfo y .t]
} [list 5 [expr [winfo screenheight .t] - 70]]
destroy .t
toplevel .t -width 80 -height 60
test unixWm-44.8 {UpdateGeometryInfo procedure, computing position} unix {
test unixWm-44.8 {UpdateGeometryInfo procedure, computing position} {unix failsOnXQuarz} {
    tkwait visibility .t
    wm overrideredirect .t 1
    update
    wm geometry .t -30+$Y2
    update
    list [winfo x .t] [winfo y .t]
} [list [expr [winfo screenwidth .t] - 110] $Y2]
1616
1617
1618
1619
1620
1621
1622
1623

1624
1625
1626
1627
1628
1629
1630
1609
1610
1611
1612
1613
1614
1615

1616
1617
1618
1619
1620
1621
1622
1623







-
+







    wm geometry .t +0+0
    tkwait visibility .t
    set property [testprop [testwrapper .t] WM_NORMAL_HINTS]
    list [expr [lindex $property 5]] [expr [lindex $property 6]] \
	    [expr [lindex $property 7]] [expr [lindex $property 8]] \
	    [expr [lindex $property 9]] [expr [lindex $property 10]]
} {40 30 320 210 10 5}
test unixWm-45.2 {UpdateSizeHints procedure} {unix testwrapper} {
test unixWm-45.2 {UpdateSizeHints procedure} {unix testwrapper failsOnUbuntu failsOnXQuarz} {
    destroy .t
    toplevel .t -width 80 -height 60
    wm minsize .t 30 40
    wm maxsize .t 200 500
    wm geometry .t +0+0
    tkwait visibility .t
    set property [testprop [testwrapper .t] WM_NORMAL_HINTS]
1644
1645
1646
1647
1648
1649
1650
1651

1652
1653
1654
1655
1656
1657
1658
1637
1638
1639
1640
1641
1642
1643

1644
1645
1646
1647
1648
1649
1650
1651







-
+







    tkwait visibility .t
    set property [testprop [testwrapper .t] WM_NORMAL_HINTS]
    list [winfo height .t] \
	    [expr [lindex $property 5]] [expr [lindex $property 6]] \
	    [expr [lindex $property 7]] [expr [lindex $property 8]] \
	    [expr [lindex $property 9]] [expr [lindex $property 10]]
} {60 40 53 320 233 10 5}
test unixWm-45.4 {UpdateSizeHints procedure, not resizable with menu} {testmenubar testwrapper} {
test unixWm-45.4 {UpdateSizeHints procedure, not resizable with menu} {testmenubar testwrapper failsOnUbuntu failsOnXQuarz} {
    destroy .t
    toplevel .t -width 80 -height 60
    frame .t.menu -height 23 -width 50
    testmenubar window .t .t.menu
    wm resizable .t 0 0
    wm geometry .t +0+0
    tkwait visibility .t
1740
1741
1742
1743
1744
1745
1746
1747

1748
1749
1750

1751
1752
1753
1754
1755
1756
1757
1733
1734
1735
1736
1737
1738
1739

1740
1741
1742

1743
1744
1745
1746
1747
1748
1749
1750







-
+


-
+







    list [catch {wm geometry .t +20-} msg] $msg
} {1 {bad geometry specifier "+20-"}}
test unixWm-48.10 {ParseGeometry procedure} unix {
    list [catch {wm geometry .t +20+10z} msg] $msg
} {1 {bad geometry specifier "+20+10z"}}
test unixWm-48.11 {ParseGeometry procedure} unix {
    catch {wm geometry .t +-10+20}
} {0}
} 0
test unixWm-48.12 {ParseGeometry procedure} unix {
    catch {wm geometry .t +30+-10}
} {0}
} 0
test unixWm-48.13 {ParseGeometry procedure, resize causes window to move} unix {
    destroy .t
    toplevel .t -width 200 -height 200
    wm geom .t +0+0
    update
    wm geom .t -0-0
    update
1798
1799
1800
1801
1802
1803
1804
1805

1806
1807
1808
1809
1810
1811
1812
1791
1792
1793
1794
1795
1796
1797

1798
1799
1800
1801
1802
1803
1804
1805







-
+







if {[tk windowingsystem] == "aqua"} {
    # Modern mac windows have no border.
    set result_50_1 {{} {} .t .t .t2 {} .t2 .t .t}
} else {
    # Windows are assumed to have a border (invisible in Gnome 3).
    set result_50_1 {{} {} .t {} .t2 {} .t2 {} .t}
}
test unixWm-50.1 {Tk_CoordsToWindow procedure, finding a toplevel, x-coords, title bar} unix {
test unixWm-50.1 {Tk_CoordsToWindow procedure, finding a toplevel, x-coords, title bar} {unix failsOnUbuntu failsOnXQuarz} {
    update
    toplevel .t -width 300 -height 400 -bg green
    wm geom .t +100+100
    tkwait visibility .t
    toplevel .t2 -width 100 -height 200 -bg red
    wm geom .t2 +200+200
    tkwait visibility .t2
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
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







-
+







-
-
-
-
+
+
+
+







-
-
-
+
+
+









-
+




-
-
-
+
+
+

-
-
+
+







	 [winfo containing [expr $x +200] [expr $y2 + 100]] \
	 [winfo containing [expr $x +200] [expr $y + 450]]
} {{} {} .t .t .t2 .t2 .t {}}
test unixWm-50.3 {
	Tk_CoordsToWindow procedure, finding a toplevel with embedding
} tempNotWin {
    deleteWindows
    catch {interp delete slave}
    catch {interp delete child}

    toplevel .t -width 300 -height 400 -bg blue
    wm geom .t +100+100
    frame .t.f -container 1 -bg red
    place .t.f -x 150 -y 50
    tkwait visibility .t.f
    update
    interp create slave
    load {} Tk slave
    slave alias frameid winfo id .t.f
    slave eval {
    interp create child
    load {} Tk child
    child alias frameid winfo id .t.f
    child eval {
	wm withdraw .
        toplevel .x -width 100 -height 80 -use [frameid] -bg yellow
        tkwait visibility .x
        update
        set x [winfo rootx .x]
        set y [winfo rooty .x]
    }
    set result [list [slave eval {winfo containing [expr $x - 1]  [expr $y + 50]}] \
	       	     [slave eval {winfo containing $x [expr $y + 50]}]]
    interp delete slave
    set result [list [child eval {winfo containing [expr $x - 1]  [expr $y + 50]}] \
	       	     [child eval {winfo containing $x [expr $y + 50]}]]
    interp delete child
    set x [winfo rootx .t]
    set y [winfo rooty .t]
    lappend result [winfo containing [expr $x + 200] [expr $y + 49]] \
	[winfo containing [expr $x + 200] [expr $y +50]]
    set result
} {{} .x .t .t.f}
test unixWm-50.4 {Tk_CoordsToWindow procedure, window in other application} unix {
    destroy .t

    catch {interp delete slave}
    catch {interp delete child}
    toplevel .t -width 200 -height 200 -bg green
    wm geometry .t +100+100
    tkwait visibility .t
    update
    interp create slave
    load {} Tk slave
    slave eval {wm geometry . 200x200+100+100; tkwait visibility . ; update}
    interp create child
    load {} Tk child
    child eval {wm geometry . 200x200+100+100; tkwait visibility . ; update}
    set result [list [winfo containing 200 200] \
	    [slave eval {winfo containing 200 200}]]
    interp delete slave
	    [child eval {winfo containing 200 200}]]
    interp delete child
    set result
} {{} .}
test unixWm-50.5 {Tk_CoordsToWindow procedure, handling menubars} {unix testmenubar} {
    deleteWindows
    toplevel .t -width 300 -height 400 -bd 2 -relief raised
    frame .t.f -width 150 -height 120 -bg green
    place .t.f -x 10 -y 150
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
1942
1943
1944
1945
1946
1947
1948

1949
1950
1951
1952
1953
1954

1955
1956
1957
1958
1959
1960
1961
1962

1963
1964
1965

1966
1967
1968
1969
1970
1971
1972
1973

1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986

1987
1988
1989
1990
1991
1992
1993
1994







-
+





-
+







-
+


-








-
+









+


-
+







	    [winfo containing $x [expr $y + 250]] \
	    [winfo containing $x [expr $y + 350]] \
	    [winfo containing $x [expr $y + 450]]
} {.t .t.f .t.f.f .t {}}
test unixWm-50.8 {Tk_CoordsToWindow procedure, more basics} unix {
    destroy .t
    toplevel .t -width 400 -height 300 -bg green
    wm geom .t +0+0
    wm geom .t +0+30
    frame .t.f -width 200 -height 100 -bd 2 -relief raised
    place .t.f -x 100 -y 100
    frame .t.f.f -width 200 -height 100 -bd 2 -relief raised
    place .t.f.f -x 100 -y 0
    update
    set x [winfo rooty .t]
    set x [winfo rootx .t]
    set y [expr [winfo rooty .t] + 150]
    list [winfo containing [expr $x + 50] $y] \
	    [winfo containing [expr $x + 150] $y] \
	    [winfo containing [expr $x + 250] $y] \
	    [winfo containing [expr $x + 350] $y] \
	    [winfo containing [expr $x + 450] $y]
} {.t .t.f .t.f.f .t {}}
test unixWm-50.9 {Tk_CoordsToWindow procedure, unmapped windows} unix {
test unixWm-50.9 {Tk_CoordsToWindow procedure, unmapped windows} {unix failsOnUbuntu} {
    destroy .t
    destroy .t2
    sleep 500		;# Give window manager time to catch up.
    toplevel .t -width 200 -height 200 -bg green
    wm geometry .t +0+0
    tkwait visibility .t
    toplevel .t2 -width 200 -height 200 -bg red
    wm geometry .t2 +0+0
    tkwait visibility .t2
    set result [list [winfo containing 100 100]]
    wm iconify .t2
    animationDelay
    update idletasks
    lappend result [winfo containing 100 100]
} {.t2 .t}
test unixWm-50.10 {Tk_CoordsToWindow procedure, unmapped windows} unix {
    destroy .t
    toplevel .t -width 200 -height 200 -bg green
    wm geometry .t +0+0
    frame .t.f -width 150 -height 150 -bd 2 -relief raised
    place .t.f -x 25 -y 25
    tkwait visibility .t.f
    update idletasks
    set result [list [winfo containing 100 100]]
    place forget .t.f
    update
    update idletasks
    lappend result [winfo containing 100 100]
} {.t.f .t}
deleteWindows
wm deiconify .

# No tests for UpdateVRootGeometry, Tk_GetVRootGeometry,
# Tk_MoveToplevelWindow, UpdateWmProtocols, or TkWmProtocolEventProc.
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
2010
2011
2012
2013
2014
2015
2016

2017
2018
2019
2020
2021
2022
2023
2024
2025
2026

2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040

2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054

2055
2056
2057
2058
2059
2060
2061
2062

2063
2064
2065

2066
2067
2068
2069
2070
2071
2072







-










-














-














-
+







-



-







    update
    raise .raise3
    raise .raise2
    raise .raise1 .raise3
    set result [winfo containing [winfo rootx .raise1] \
	    [winfo rooty .raise1]]
    destroy .raise2
    sleep 500
    list $result [winfo containing [winfo rootx .raise1] \
	    [winfo rooty .raise1]]
} {.raise2 .raise1}
test unixWm-51.4 {TkWmRestackToplevel procedure, basic tests} {unix nonPortable} {
    makeToplevels
    raise .raise2
    raise .raise1
    lower .raise3 .raise1
    set result [winfo containing 100 100]
    destroy .raise1
    sleep 500
    lappend result [winfo containing 100 100]
} {.raise1 .raise3}
test unixWm-51.5 {TkWmRestackToplevel procedure, basic tests} {unix nonPortable} {
    makeToplevels
    update
    raise .raise2
    raise .raise1
    raise .raise3
    frame .raise1.f1
    frame .raise1.f1.f2
    lower .raise3 .raise1.f1.f2
    set result [winfo containing [winfo rootx .raise1] \
	    [winfo rooty .raise1]]
    destroy .raise1
    sleep 500
    list $result [winfo containing [winfo rootx .raise2] \
	    [winfo rooty .raise2]]
} {.raise1 .raise3}
deleteWindows
test unixWm-51.6 {TkWmRestackToplevel procedure, window to be stacked isn't mapped} unix {
    destroy .t
    toplevel .t -width 200 -height 200 -bg green
    wm geometry .t +0+0
    tkwait visibility .t
    destroy .t2
    toplevel .t2 -width 200 -height 200 -bg red
    wm geometry .t2 +0+0
    winfo containing 100 100
} {.t}
test unixWm-51.7 {TkWmRestackToplevel procedure, other window isn't mapped} unix {
test unixWm-51.7 {TkWmRestackToplevel procedure, other window isn't mapped} {unix failsOnXQuarz} {
    foreach w {.t .t2 .t3} {
	destroy $w
	update
	toplevel $w -width 200 -height 200 -bg green
	wm geometry $w +0+0
    }
    raise .t .t2
    sleep 2000
    update
    set result [list [winfo containing 100 100]]
    lower .t3
    sleep 2000
    lappend result [winfo containing 100 100]
} {.t3 .t}
test unixWm-51.8 {TkWmRestackToplevel procedure, overrideredirect windows} unix {
    destroy .t
    toplevel .t -width 200 -height 200 -bg green
    wm overrideredirect .t 1
    wm geometry .t +0+0
2246
2247
2248
2249
2250
2251
2252
2253

2254
2255
2256
2257
2258
2259
2260
2234
2235
2236
2237
2238
2239
2240

2241
2242
2243
2244
2245
2246
2247
2248







-
+







    .m add command -label Second
    .m add command -label Third
    .m post 30 30
    update
    set result [wm overrideredirect .m]
    destroy .m
    set result
} {1}
} 1

# No tests for TkGetPointerCoords, CreateWrapper, or GetMaxSize.

test unixWm-55.1 {TkUnixSetMenubar procedure} {unix testmenubar} {
    destroy .t
    toplevel .t -width 300 -height 200 -bd 2 -relief raised
    wm geom .t +0+0

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 (c) 1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44







-
+







    .l yview scroll a
} -returnCodes error -result {wrong # args: should be ".l yview scroll number pages|units"}
test util-1.5 {Tk_GetScrollInfo procedure} -body {
    .l yview scroll a b c
} -returnCodes error -result {wrong # args: should be ".l yview scroll number pages|units"}
test util-1.6 {Tk_GetScrollInfo procedure} -body {
    .l yview scroll xyz units
} -returnCodes error -result {expected integer but got "xyz"}
} -returnCodes error -result {expected floating-point number but got "xyz"}
test util-1.7 {Tk_GetScrollInfo procedure} -body {
    .l yview 0
    .l yview scroll 2 pages
    .l nearest 0
} -result 6
test util-1.8 {Tk_GetScrollInfo procedure} -body {
    .l yview 15

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 (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 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 source [file join [testsDirectory] $file]
    uplevel #0 [list source -encoding utf-8 [file join [testsDirectory] $file]]
    concat ""
    } {}
    incr testNum
}

# The following procedure is invoked to print the contents of a canvas:

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 (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 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 (c) 1997 by Sun Microsystems, Inc.
# Copyright (c) 1998-2000 by Scriptics Corporation.
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 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
97
66
67
68
69
70
71
72

73
74
75
76
77

78
79
80
81
82
83
84

85
86
87
88

89

90
91
92
93
94
95
96







-
+




-
+






-
+



-
+
-








test winClipboard-1.5 {TkSelGetSelection & TkWinClipboardRender} -constraints {
    win testclipboard
} -setup {
    clipboard clear
} -body {
    set map [list "\r" "\\r" "\n" "\\n"]
    clipboard append "line 1\u00c7\nline 2"
    clipboard append "line 1Ç\nline 2"
    list [string map $map [selection get -selection CLIPBOARD]]\
        [string map $map [testclipboard]]
} -cleanup {
    clipboard clear
} -result [list "line 1\u00c7\\nline 2" "line 1\u00c7\\nline 2"]
} -result [list "line 1Ç\\nline 2" "line 1Ç\\nline 2"]

test winClipboard-1.6 {TkSelGetSelection & TkWinClipboardRender} -constraints {
    win testclipboard
} -setup {
    clipboard clear
} -body {
    clipboard append "\u043f\u0440\u0438\u0432\u0435\u0442 \u043c\u0438\u0444"
    clipboard append "привет миф"
    list [selection get -selection CLIPBOARD] [testclipboard]
} -cleanup {
    clipboard clear
} -result [list "\u043f\u0440\u0438\u0432\u0435\u0442 \u043c\u0438\u0444"\
} -result [list "привет миф" "привет миф"]
              "\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 (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright (c) 1998-1999 ActiveState Corporation.
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# Copyright © 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 "\u041f\u0440\u0438\u0432\u0435\u0442"]
                     -title "Привет"]
    }
    then {
        if {[catch {
            array set a [testgetwindowinfo $::tk_dialog]
            if {[info exists a(text)]} {lappend x $a(text)}
        } err]} { lappend x $err }
        lappend x [Click ok]
    }
    lappend x $clr
} -result [list "\u041f\u0440\u0438\u0432\u0435\u0442" 0 "#ff9933"]
} -result [list "Привет" 0 "#ff9933"]
test winDialog-1.6 {Tk_ChooseColorObjCmd: -parent} -constraints {
    testwinevent
} -setup {
    catch {unset a x}
} -body {
    start {set clr [tk_chooseColor -initialcolor "#ff9933" -parent .]}
    set x {}
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 "\u0167\u00e9\u015d\u0167"]
    set dir [tcltest::makeDirectory "ŧéŝŧ"]
    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 "\u0167\u00e9\u015d\u0167"]
    set dir [tcltest::makeDirectory "ŧéŝŧ"]
    set path [tcltest::makeFile "" testfile $dir]
    unset -nocomplain x
    start {set x [tk_getOpenFile \
                      -initialdir $dir \
                      -initialfile "testfile" -title Foo]}
    then {
        Click ok
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 {\u2022\u2022\u2022\u2022}}}}]}
    start {set x [catch {tk_getSaveFile -filetypes {{"foo" .foo {••••}}}}]}
    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  "\u041f\u0440\u0438\u0432\u0435\u0442"
            -title  "Привет"
        tk fontchooser show
    }
    then {
        array set a [testgetwindowinfo $::tk_dialog]
        Click cancel
    }
    set a(text)
} -result "\u041f\u0440\u0438\u0432\u0435\u0442"
} -result "Привет"

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 (c) 1996-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1996-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

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 (c) 1995-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1995-1996 Sun Microsystems, Inc.
# Copyright © 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 (c) 2007 Pat Thoyts <[email protected]>
# Copyright © 2007 Pat Thoyts <[email protected]>

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 "\u041f\u043e\u0438\u0441\u043a\u0020\u0441\u0442\u0440\u0430\u043d\u0438\u0446"
    set message "Поиск страниц"
    after 100 [list GetWindowInfo $title 2]
    set r [tk_messageBox -type ok -title $title -message $message]
    array set info $windowInfo
    lappend r $info(childtext)
} -cleanup {
    wm deiconify .
} -result [list ok "\u041f\u043e\u0438\u0441\u043a\u0020\u0441\u0442\u0440\u0430\u043d\u0438\u0446"]
} -result [list ok "Поиск страниц"]

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 "\u041f\u043e\u0438\u0441\u043a"
    set detail "\u0441\u0442\u0440\u0430\u043d\u0438\u0446"
    set message "Поиск"
    set detail "страниц"
    after 100 [list GetWindowInfo $title 2]
    set r [tk_messageBox -type ok -title $title -message $message -detail $detail]
    array set info $windowInfo
    lappend r $info(childtext)
} -cleanup {
    wm deiconify .
} -result [list ok "\u041f\u043e\u0438\u0441\u043a\n\n\u0441\u0442\u0440\u0430\u043d\u0438\u0446"]
} -result [list ok "Поиск\n\nстраниц"]

# -------------------------------------------------------------------------

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
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 "send" command and the
# other procedures in the file tkSend.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.1
package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

# Compute a script that will load Tk into a child interpreter.

foreach pkg [info loaded] {
    if {[lindex $pkg 1] == "Tk"} {
148
149
150
151
152
153
154
155

156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174

175
176
177
178
179
180
181
148
149
150
151
152
153
154

155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
181







-
+


















-
+







    list [catch {send $interp {expr {2 / 0}}} msg] $msg $errorCode $errorInfo
} "1 {divide by zero} {ARITH DIVZERO {divide by zero}} {divide by zero\n    while executing\n\"expr {2 / 0}\"\n    invoked from within\n\"send \$interp {expr {2 / 0}}\"}"

test winSend-3.1 {TkGetInterpNames} winSend {
    set origLength [llength $currentInterps]
    set newLength [llength [winfo interps]]
    expr {($newLength - 2) == $origLength}
} {1}
} 1

test winSend-4.1 {DeleteProc - changing name of app} winSend {
    newApp a
    list [a eval tk appname foo] [interp delete a]
} {foo {}}
test winSend-4.2 {DeleteProc - normal} winSend {
    newApp a
    list [interp delete a]
} {{}}

test winSend-5.1 {ExecuteRemoteObject - no error} winSend {
    set newInterps [winfo interps]
    foreach interp $newInterps {
	if {[lsearch $currentInterps $interp] < 0} {
	    break
	}
    }
    list [send $interp {send [tk appname] {expr {2 / 1}}}]
} {2}
} 2
test winSend-5.2 {ExecuteRemoteObject - error} winSend {
    set newInterps [winfo interps]
    foreach interp $newInterps {
	if {[lsearch $currentInterps $interp] < 0} {
	    break
	}
    }
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







-
+







    foreach interp $newInterps {
	if {[lsearch $currentInterps $interp] < 0} {
	    break
	}
    }
    set command "dde services Tk {}"
    list [catch "send \{$interp\} \{$command\}"]
} {0}
} 0

test winSend-7.1 {DDEExitProc} winSend {
    newApp testApp
    list [interp delete testApp]
} {{}}

test winSend-8.1 {SendDdeConnect} winSend {
308
309
310
311
312
313
314
315

316
317
318

319
320
321
322
323
324
325
308
309
310
311
312
313
314

315
316
317

318
319
320
321
322
323
324
325







-
+


-
+







    list [catch {dde request} msg] $msg
} {1 {wrong # args: should be "dde request serviceName topicName value"}}
test winSend-10.7 {Tk_DDEObjCmd - services wrong num args} winSend {
    list [catch {dde services} msg] $msg
} {1 {wrong # args: should be "dde services serviceName topicName"}}
test winSend-10.8 {Tk_DDEObjCmd - null service name} winSend {
    list [catch {dde services {} {tktest #2}}]
} {0}
} 0
test winSend-10.9 {Tk_DDEObjCmd - null topic name} winSend {
    list [catch {dde services {Tk} {}}]
} {0}
} 0
test winSend-10.10 {Tk_DDEObjCmd - execute - nothing to execute} winSend {
    set newInterps [winfo interps]
    foreach interp $newInterps {
	if {[lsearch $currentInterps $interp] < 0} {
	    break
	}
    }

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
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 tests  is a Tcl script to test the procedures in the file
# tkWinWm.c.  It is organized in the standard fashion for Tcl tests.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1996 by Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 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(CI)] || ![string match Linux $::tcl_platform(os)]}]

test winWm-1.1 {TkWmMapWindow} -constraints win -setup {
    destroy .t
} -body {
    toplevel .t
    wm override .t 1
    wm geometry .t +0+0
481
482
483
484
485
486
487
488

489
490
491
492
493
494
495
482
483
484
485
486
487
488

489
490
491
492
493
494
495
496







-
+







    vwait winwm90done
    set winwm90done
} -cleanup {
    foreach cmd {proc1 proc2 proc3 click} {
        rename winwm90$cmd {}
    }
    destroy .tx .t .sd
} -result {ok}
} -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
526
527
528
529
530
531
532
533

534
535

536
537
538
539
540
541
542
543
544

545
546
547

548
549
550

551
552

553
554
555
556
557
558
559
527
528
529
530
531
532
533

534
535

536
537
538
539
540
541
542
543
544

545
546
547

548
549
550

551
552

553
554
555
556
557
558
559
560







-
+

-
+








-
+


-
+


-
+

-
+







    vwait winwm91done
    set winwm91done
} -cleanup {
    foreach cmd {proc1 proc2 proc3 click} {
        rename winwm91$cmd {}
    }
    destroy .tx .t .sd
} -result {ok}
} -result ok

test winWm-9.2 "check wm forget for unmapped parent (#3205464,#2967911)" -setup {
test winWm-9.2 "check wm forget for unmapped parent (#3205464,#2967911)" -constraints failsOnUbuntu -setup {
    destroy .t
    toplevel .t
    set winwm92 {}
    frame .t.f -background blue -height 200 -width 200
    frame .t.f.x -background red -height 100 -width 100
} -body {
    pack .t.f.x
    pack .t.f
    lappend aid [after 2000 {set ::winwm92 timeout}] [after 100 {
    lappend aid [after 5000 {set ::winwm92 timeout}] [after 500 {
        wm manage .t.f
        wm iconify .t
        lappend aid [after 100 {
        lappend aid [after 500 {
            wm forget .t.f
            wm deiconify .t
            lappend aid [after 100 {
            lappend aid [after 500 {
                pack .t.f
                lappend aid [after 100 {
                lappend aid [after 500 {
		    set ::winwm92 [expr {
			    [winfo rooty .t.f.x] == 0 ? "failed" : "ok"}]}]
            }]
        }]
    }]
    vwait ::winwm92
    foreach id $aid {

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 (c) 1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1995 Sun Microsystems, Inc.
# Copyright © 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

Changes to tests/winfo.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



-
-
-
+
+
+






+
+
+







# This file is a Tcl script to test out the "winfo" command.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 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(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:
# w -        Name of toplevel window to create.
287
288
289
290
291
292
293
294

295
296
297
298
299
300
301
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} -body {
test winfo-9.4 {"winfo viewable" command} -constraints failsOnUbuntu -body {
    wm iconify .
    winfo viewable .
} -cleanup {
    wm deiconify .
} -result 0
test winfo-9.5 {"winfo viewable" command} -setup {
    deleteWindows
316
317
318
319
320
321
322
323

324
325
326
327
328
329
330
319
320
321
322
323
324
325

326
327
328
329
330
331
332
333







-
+







    frame .f1.f2 -width 50 -height 50 -relief raised -bd 2
    place .f1.f2 -x 0 -y 0
    update
    list [winfo viewable .f1] [winfo viewable .f1.f2]
} -cleanup {
    deleteWindows
} -result {0 0}
test winfo-9.7 {"winfo viewable" command} -setup {
test winfo-9.7 {"winfo viewable" command} -constraints {failsOnUbuntu failsOnXQuarz} -setup {
    deleteWindows
} -body {
    frame .f1 -width 100 -height 100 -relief raised -bd 2
    place .f1 -x 0 -y 0
    frame .f1.f2 -width 50 -height 50 -relief raised -bd 2
    place .f1.f2 -x 0 -y 0
    update

Changes to tests/wm.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
1
2
3
4



5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46
47
48




-
-
-
+
+
+






-
+















+
+
+






-
+
+
+







# This file is a Tcl script to test out Tk's interactions with the window
# manager, including the "wm" command. It is organized in the standard fashion
# for Tcl tests.
#
# Copyright (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 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.1
package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

wm deiconify .
if {![winfo ismapped .]} {
    tkwait visibility .
}

proc stdWindow {} {
    destroy .t
    toplevel .t -width 100 -height 50
    wm geom .t +0+0
    update
}

testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint 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
    after 100;
    update
    update idletasks
}

# How to carry out a small delay while processing events

proc eventDelay {{delay 200}} {
    after $delay "set done 1" ; vwait done
}
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
784
785
786
787
788
789
790

791
792
793
794
795
796
797
798
799
800

801
802
803
804
805
806
807
808
809
810

811
812

813
814
815

816
817
818

819
820
821
822
823
824
825
826







-
+









-
+









-
+

-
+


-
+


-
+







test wm-iconify-2.3 {Misc errors} -body {
    toplevel .t2
    wm geom .t2 +0+0
    wm iconwindow .t .t2
    wm iconify .t2
} -returnCodes error -cleanup {
    destroy .t2
} -result {can't iconify .t2: it is an icon for .t}
} -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} -body {
test wm-iconify-3.1 {iconify behavior} -constraints failsOnUbuntu -body {
    toplevel .t2
    wm geom .t2 -0+0
    update
    update idletasks
    set result [winfo ismapped .t2]
    wm iconify .t2
    update
    update idletasks
    lappend result [winfo ismapped .t2]
} -cleanup {
    destroy .t2
} -result {1 0}


### wm iconmask ###
1409
1410
1411
1412
1413
1414
1415
1416

1417
1418
1419
1420
1421
1422
1423
1414
1415
1416
1417
1418
1419
1420

1421
1422
1423
1424
1425
1426
1427
1428







-
+







    deleteWindows
} -body {
    wm stackorder .
} -result {.}

deleteWindows

test wm-stackorder-3.1 {unmapped toplevel} -body {
test wm-stackorder-3.1 {unmapped toplevel} -constraints failsOnUbuntu -body {
    toplevel .t1 ; update
    toplevel .t2 ; update
    wm iconify .t1
    wm stackorder .
} -cleanup {
    destroy .t1 .t2
} -result {. .t2}
1519
1520
1521
1522
1523
1524
1525
1526

1527
1528
1529
1530
1531
1532
1533
1524
1525
1526
1527
1528
1529
1530

1531
1532
1533
1534
1535
1536
1537
1538







-
+







    raise .
    raiseDelay
    wm stackorder .
} -cleanup {
    destroy .t
} -result {.t .}
test wm-stackorder-5.2 {A normal toplevel can't be raised above an \
    overrideredirect toplevel on unix} -constraints x11 -body {
    overrideredirect toplevel on unix} -constraints {x11 failsOnUbuntu failsOnXQuarz} -body {
    toplevel .t
    tkwait visibility .t
    wm overrideredirect .t 1
    raise .
    update
    raiseDelay
    wm stackorder . isabove .t
1543
1544
1545
1546
1547
1548
1549
1550

1551
1552
1553
1554
1555
1556
1557
1548
1549
1550
1551
1552
1553
1554

1555
1556
1557
1558
1559
1560
1561
1562







-
+







    update
    raiseDelay
    wm stackorder . isabove .t
} -cleanup {
    destroy .t
} -result 1
test wm-stackorder-5.3 {An overrideredirect window\
        can be explicitly lowered} -body {
        can be explicitly lowered} -constraints failsOnXQuarz -body {
    toplevel .t
    tkwait visibility .t
    wm overrideredirect .t 1
    lower .t
    update
    raiseDelay
    wm stackorder .t isbelow .
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
1596
1597
1598
1599
1600
1601
1602

1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613

1614
1615

1616
1617
1618
1619
1620
1621
1622
1623







-
+










-
+

-
+







} -result {t Apa {}}


### wm transient ###
test wm-transient-1.1 {usage} -returnCodes error -body {
    catch {destroy .t} ; toplevel .t
    wm transient .t 1 2
} -result {wrong # args: should be "wm transient window ?master?"}
} -result {wrong # args: should be "wm transient window ?window?"}
test wm-transient-1.2 {usage} -returnCodes error -body {
    catch {destroy .t} ; toplevel .t
    wm transient .t foo
} -result {bad window path name "foo"}
test wm-transient-1.3 {usage} -returnCodes error -body {
    catch {destroy .t} ; toplevel .t
    wm transient foo .t
} -result {bad window path name "foo"}
deleteWindows
test wm-transient-1.4 {usage} -returnCodes error -body {
    toplevel .master
    toplevel .top
    toplevel .subject
    wm transient .subject .master
    wm transient .subject .top
    wm iconify .subject
} -cleanup {
    deleteWindows
} -result {can't iconify ".subject": it is a transient}
test wm-transient-1.5 {usage} -returnCodes error -body {
    toplevel .icon -bg blue
    toplevel .top
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
1631
1632
1633
1634
1635
1636
1637

1638
1639


1640
1641
1642
1643

1644
1645
1646
1647
1648
1649
1650
1651
1652
1653

1654
1655



1656
1657
1658
1659
1660

1661
1662

1663
1664
1665

1666
1667
1668

1669
1670
1671
1672
1673
1674




1675
1676
1677
1678
1679

1680
1681
1682
1683

1684
1685
1686



1687
1688
1689
1690
1691

1692
1693
1694
1695
1696
1697
1698



1699
1700
1701
1702
1703
1704

1705
1706
1707
1708
1709
1710

1711
1712
1713
1714

1715
1716
1717


1718
1719
1720
1721

1722
1723
1724
1725
1726
1727
1728
1729



1730
1731
1732
1733
1734

1735
1736
1737
1738
1739
1740
1741


1742
1743
1744


1745
1746
1747



1748
1749
1750
1751
1752
1753
1754


1755
1756
1757
1758

1759
1760




1761
1762
1763
1764
1765


1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776

1777
1778
1779

1780
1781
1782

1783
1784
1785

1786
1787
1788
1789
1790
1791

1792
1793

1794
1795

1796
1797

1798
1799
1800
1801
1802
1803
1804


1805
1806
1807


1808
1809
1810
1811
1812
1813
1814
1815


1816
1817
1818
1819

1820
1821


1822
1823
1824
1825
1826
1827
1828
1829
1830

1831
1832
1833

1834
1835
1836

1837
1838


1839
1840
1841
1842
1843
1844
1845

1846
1847

1848
1849
1850
1851
1852
1853
1854
1855


1856
1857
1858
1859
1860
1861



1862
1863
1864
1865
1866
1867
1868
1869
1870
1871

1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885


1886
1887
1888


1889
1890
1891
1892
1893
1894

1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906

1907
1908
1909
1910
1911
1912
1913
1914







-
+

-
-
+
+


-
+









-
+

-
-
-
+
+
+


-
+

-
+


-
+


-
+





-
-
-
-
+
+
+
+

-
+



-
+


-
-
-
+
+
+


-
+






-
-
-
+
+
+



-
+





-
+



-
+


-
-
+
+


-
+







-
-
-
+
+
+


-
+






-
-
+
+

-
-
+
+

-
-
-
+
+
+




-
-
+
+


-
+

-
-
-
-
+
+
+
+

-
-
+
+









-
+


-
+


-
+


-
+





-
+

-
+

-
+

-
+






-
-
+
+

-
-
+
+






-
-
+
+


-
+

-
-
+
+







-
+


-
+


-
+

-
-
+
+





-
+

-
+







-
-
+
+




-
-
-
+
+
+







-
+













-
-
+
+

-
-
+
+




-
+











-
+







    toplevel .icon -bg blue
    toplevel .top
    wm iconwindow .top .icon
    toplevel .dummy
    wm transient .dummy .icon
} -cleanup {
    deleteWindows
} -result {can't make ".icon" a master: it is an icon for .top}
} -result {can't make ".icon" a container: it is an icon for .top}
test wm-transient-1.7 {usage} -returnCodes error -body {
    toplevel .master
    wm transient .master .master
    toplevel .top
    wm transient .top .top
} -cleanup {
    deleteWindows
} -result {setting ".master" as master creates a transient/master cycle}
} -result {can't set ".top" as container: would cause management loop}
test wm-transient-1.8 {usage} -returnCodes error -body {
    toplevel .t1
    toplevel .t2
    toplevel .t3
    wm transient .t2 .t1
    wm transient .t3 .t2
    wm transient .t1 .t3
} -cleanup {
    deleteWindows
} -result {setting ".t3" as master creates a transient/master cycle}
} -result {can't set ".t3" as container: would cause management loop}
test wm-transient-1.9 {usage} -returnCodes error -body {
    toplevel .master
    frame .master.f
    wm transient .master .master.f
    toplevel .top
    frame .top.f
    wm transient .top .top.f
} -cleanup {
    deleteWindows
} -result {setting ".master" as master creates a transient/master cycle}
} -result {can't set ".top" as container: would cause management loop}

test wm-transient-2.1 {basic get/set of master} -setup {
test wm-transient-2.1 {basic get/set of toplevel} -setup {
    set results [list]
} -body {
    toplevel .master
    toplevel .top
    toplevel .subject
    lappend results [wm transient .subject]
    wm transient .subject .master
    wm transient .subject .top
    lappend results [wm transient .subject]
    wm transient .subject {}
    lappend results [wm transient .subject]
} -cleanup {
    deleteWindows
} -result {{} .master {}}
test wm-transient-2.2 {first toplevel parent of non-toplevel master is used} -body {
    toplevel .master
    frame .master.f
} -result {{} .top {}}
test wm-transient-2.2 {first toplevel parent of non-toplevel container window is used} -body {
    toplevel .top
    frame .top.f
    toplevel .subject
    wm transient .subject .master.f
    wm transient .subject .top.f
    wm transient .subject
} -cleanup {
    deleteWindows
} -result {.master}
} -result {.top}

test wm-transient-3.1 {transient toplevel is withdrawn
        when mapped if master is withdrawn} -body {
    toplevel .master
    wm withdraw .master
        when mapped if toplevel is withdrawn} -body {
    toplevel .top
    wm withdraw .top
    update
    toplevel .subject
    wm transient .subject .master
    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 master} -body {
    toplevel .master
    wm withdraw .master
        takes on withdrawn state of toplevel} -body {
    toplevel .top
    wm withdraw .top
    update
    toplevel .subject
    update
    wm transient .subject .master
    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 master
test wm-transient-3.3 {withdraw/deiconify on the toplevel
        also does a withdraw/deiconify on the transient} -setup {
    set results [list]
} -body {
    toplevel .master
    toplevel .top
    toplevel .subject
    update
    wm transient .subject .master
    wm withdraw .master
    wm transient .subject .top
    wm withdraw .top
    update
    lappend results [wm state .subject] [winfo ismapped .subject]
    wm deiconify .master
    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 master is iconic} -body {
    toplevel .master
    wm iconify .master
        when mapped if toplevel is iconic} -constraints {failsOnUbuntu failsOnXQuarz} -body {
    toplevel .top
    wm iconify .top
    update
    toplevel .subject
    wm transient .subject .master
    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 master is iconic} -body {
    toplevel .master
        is withdrawn if toplevel is iconic} -constraints failsOnUbuntu -body {
    toplevel .top
    raiseDelay
    wm iconify .master
    update
    wm iconify .top
    update idletasks
    toplevel .subject
    update
    wm transient .subject .master
    update
    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 master
        does a withdraw/deiconify on the transient} -setup {
test wm-transient-4.3 {iconify/deiconify on the toplevel
        does a withdraw/deiconify on the transient} -constraints failsOnUbuntu -setup {
    set results [list]
} -body {
    toplevel .master
    toplevel .top
    toplevel .subject
    update
    wm transient .subject .master
    wm iconify .master
    update
    update idletasks
    wm transient .subject .top
    wm iconify .top
    update idletasks
    lappend results [wm state .subject] [winfo ismapped .subject]
    wm deiconify .master
    update
    wm deiconify .top
    update idletasks
    lappend results [wm state .subject] [winfo ismapped .subject]
} -cleanup {
    deleteWindows
} -result {withdrawn 0 normal 1}

test wm-transient-5.1 {an error during transient command should not
        cause the map/unmap binding to be deleted} -setup {
    set results [list]
} -body {
    toplevel .master
    toplevel .top
    toplevel .subject
    update
    wm transient .subject .master
    wm transient .subject .top
    # Expect a bad window path error here
    lappend results [catch {wm transient .subject .bad}]
    wm withdraw .master
    wm withdraw .top
    update
    lappend results [wm state .subject]
    wm deiconify .master
    wm deiconify .top
    update
    lappend results [wm state .subject]
} -cleanup {
    deleteWindows
} -result {1 withdrawn normal}
test wm-transient-5.2 {remove transient property when master
test wm-transient-5.2 {remove transient property when toplevel
        is destroyed} -body {
    toplevel .master
    toplevel .top
    toplevel .subject
    wm transient .subject .master
    wm transient .subject .top
    update
    destroy .master
    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 master is destroyed} -body {
    toplevel .master
        that had never been mapped when toplevel is destroyed} -body {
    toplevel .top
    toplevel .subject
    wm transient .subject .master
    destroy .master
    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 master} -body {
    toplevel .master
        state changes in the toplevel} -body {
    toplevel .top
    toplevel .subject
    update
    wm transient .subject .master
    wm transient .subject .top
    wm withdraw .subject
    wm withdraw .master
    wm deiconify .master
    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 master} -setup {
        state changes in the toplevel} -setup {
    set results [list]
} -body {
    toplevel .master
    toplevel .top
    toplevel .subject
    update
    wm transient .subject .master
    wm transient .subject .top
    wm withdraw .subject
    wm withdraw .master
    wm deiconify .master
    wm withdraw .top
    wm deiconify .top
    # idle handler should not map the transient
    update
    lappend results [wm state .subject]
    wm deiconify .subject
    lappend results [wm state .subject]
    wm withdraw .master
    wm withdraw .top
    lappend results [wm state .subject]
    wm deiconify .master
    wm deiconify .top
    # idle handler should map transient
    update
    lappend results [wm state .subject]
} -cleanup {
    deleteWindows
} -result {withdrawn normal withdrawn normal}
test wm-transient-6.3 {a withdrawn transient does not track
        state changes in the master} -body {
    toplevel .master
        state changes in the toplevel} -body {
    toplevel .top
    toplevel .subject
    update
    # withdraw before making window a transient
    wm withdraw .subject
    wm transient .subject .master
    wm withdraw .master
    wm deiconify .master
    wm transient .subject .top
    wm withdraw .top
    wm deiconify .top
    # idle handler should not map the transient
    update
    wm state .subject
} -cleanup {
    deleteWindows
} -result {withdrawn}

# wm-transient-7.*: See SF Tk Bug #592201 "wm transient fails with two masters"
# wm-transient-7.*: See SF Tk Bug #592201 "wm transient fails with two toplevels"
# wm-transient-7.3 through 7.5 all caused panics on Unix in Tk 8.4b1.
# 7.1 and 7.2 added to catch (potential) future errors.
#
test wm-transient-7.1 {Destroying transient} -body {
    toplevel .t
    toplevel .transient
    wm transient .transient .t
    destroy .transient
    destroy .t
    # OK: the above did not cause a panic.
} -cleanup {
    deleteWindows
}
test wm-transient-7.2 {Destroying master} -body {
    toplevel .t
test wm-transient-7.2 {Destroying toplevel} -body {
    toplevel .top
    toplevel .transient
    wm transient .transient .t
    destroy .t
    wm transient .transient .top
    destroy .top
    wm transient .transient
} -cleanup {
    deleteWindows
} -result {}
test wm-transient-7.3 {Reassign transient, destroy old master} -body {
test wm-transient-7.3 {Reassign transient, destroy old toplevel} -body {
    toplevel .t1
    toplevel .t2
    toplevel .transient
    wm transient .transient .t1
    wm transient .transient .t2
    destroy .t1	;# Caused panic in 8.4b1
    destroy .t2
    destroy .transient
} -cleanup {
    deleteWindows
}
test wm-transient-7.4 {Reassign transient, destroy new master} -body {
test wm-transient-7.4 {Reassign transient, destroy new toplevel} -body {
    toplevel .t1
    toplevel .t2
    toplevel .transient
    wm transient .transient .t1
    wm transient .transient .t2
    destroy .t2 	;# caused panic in 8.4b1
    destroy .t1
1920
1921
1922
1923
1924
1925
1926
1927

1928
1929
1930
1931
1932


1933
1934
1935
1936
1937
1938
1939
1925
1926
1927
1928
1929
1930
1931

1932
1933
1934
1935


1936
1937
1938
1939
1940
1941
1942
1943
1944







-
+



-
-
+
+







    destroy .transient
    destroy .t2 	;# caused panic in 8.4b1
    destroy .t1		;# so did this
} -cleanup {
    deleteWindows
}

test wm-transient-8.1 {transient to withdrawn window, Bug 1163496} -setup {
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 masters, even if they were
    # made transients when those masters were withdrawn.
    # Verifies that transients stay on top of their toplevels, even if they were
    # made transients when those toplevels were withdrawn.
    toplevel .t1; wm withdraw  .t1;     update
    toplevel .t2; wm transient .t2 .t1; update
    lappend result [winfo ismapped .t1] [winfo ismapped .t2]
    wm deiconify .t1; update
    lappend result [winfo ismapped .t1] [winfo ismapped .t2]
    raise .t1; update
    lappend result [lsearch -all -inline -glob [wm stackorder .] ".t?"]
1997
1998
1999
2000
2001
2002
2003
2004

2005
2006
2007
2008
2009
2010
2011
2012

2013
2014
2015
2016
2017
2018
2019
2002
2003
2004
2005
2006
2007
2008

2009
2010
2011
2012
2013
2014
2015
2016

2017
2018
2019
2020
2021
2022
2023
2024







-
+







-
+







test wm-state-2.7 {state change before map} -body {
    toplevel .t
    wm iconify .t
    wm state .t
} -cleanup {
    deleteWindows
} -result {iconic}
test wm-state-2.8 {state change after map} -body {
test wm-state-2.8 {state change after map} -constraints failsOnUbuntu -body {
    toplevel .t
    update
    wm state .t iconic
    wm state .t
} -cleanup {
    deleteWindows
} -result {iconic}
test wm-state-2.9 {state change after map} -body {
test wm-state-2.9 {state change after map} -constraints failsOnUbuntu -body {
    toplevel .t
    update
    wm iconify .t
    wm state .t
} -cleanup {
    deleteWindows
} -result {iconic}
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
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







+
+
+
+
+







-


-
+


-
+


-
+







} -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
    update
    set res [winfo manager .f]
    pack forget .f
    update
    doUpdate
    lappend res [winfo manager .f]
    wm manage .f
    update
    doUpdate
    lappend res [winfo manager .f]
    wm forget .f
    update
    doUpdate
    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 (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 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.

388
389
390
391
392
393
394
395

396
397
398
399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
388
389
390
391
392
393
394

395
396
397
398
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413







-
+










-
+








STUB_LIB_OBJS = tkStubLib.o ttkStubLib.o

X11_OBJS = tkUnix.o tkUnix3d.o tkUnixButton.o tkUnixColor.o tkUnixConfig.o \
	tkUnixCursor.o tkUnixDraw.o tkUnixEmbed.o tkUnixEvent.o \
	tkUnixFocus.o  $(FONT_OBJS) tkUnixInit.o tkUnixKey.o tkUnixMenu.o \
	tkUnixMenubu.o tkUnixScale.o tkUnixScrlbr.o tkUnixSelect.o \
	tkUnixSend.o tkUnixWm.o tkUnixXId.o
	tkUnixSend.o tkUnixSysNotify.o tkUnixSysTray.o tkUnixWm.o tkUnixXId.o

AQUA_OBJS = tkMacOSXBitmap.o tkMacOSXButton.o tkMacOSXClipboard.o \
	tkMacOSXColor.o tkMacOSXConfig.o tkMacOSXCursor.o tkMacOSXDebug.o \
	tkMacOSXDialog.o tkMacOSXDraw.o tkMacOSXEmbed.o tkMacOSXEntry.o \
	tkMacOSXEvent.o tkMacOSXFont.o tkMacOSXHLEvents.o tkMacOSXImage.o \
	tkMacOSXInit.o tkMacOSXKeyboard.o tkMacOSXKeyEvent.o \
	tkMacOSXMenu.o \
	tkMacOSXMenubutton.o tkMacOSXMenus.o tkMacOSXMouseEvent.o \
	tkMacOSXNotify.o tkMacOSXRegion.o tkMacOSXScrlbr.o tkMacOSXSend.o \
	tkMacOSXServices.o tkMacOSXSubwindows.o tkMacOSXWindowEvent.o \
	tkMacOSXWm.o tkMacOSXXStubs.o \
	tkMacOSXWm.o tkMacOSXXStubs.o tkMacOSXSysTray.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) \
509
510
511
512
513
514
515
516
517
518



519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535

536
537
538
539
540
541
542
509
510
511
512
513
514
515



516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534

535
536
537
538
539
540
541
542







-
-
-
+
+
+
















-
+







	$(UNIX_DIR)/tkUnixEmbed.c $(UNIX_DIR)/tkUnixEvent.c \
	$(UNIX_DIR)/tkUnixFocus.c \
	$(UNIX_DIR)/tkUnixRFont.c \
	$(UNIX_DIR)/tkUnixFont.c $(UNIX_DIR)/tkUnixInit.c \
	$(UNIX_DIR)/tkUnixKey.c \
	$(UNIX_DIR)/tkUnixMenu.c $(UNIX_DIR)/tkUnixMenubu.c \
	$(UNIX_DIR)/tkUnixScale.c $(UNIX_DIR)/tkUnixScrlbr.c \
	$(UNIX_DIR)/tkUnixSelect.c \
	$(UNIX_DIR)/tkUnixSend.c $(UNIX_DIR)/tkUnixWm.c \
	$(UNIX_DIR)/tkUnixXId.c
	$(UNIX_DIR)/tkUnixSelect.c $(UNIX_DIR)/tkUnixSend.c \
	$(UNIX_DIR)/tkUnixSysNotify $(UNIX_DIR)/tkUnixSysTray.c \
	$(UNIX_DIR)/tkUnixWm.c $(UNIX_DIR)/tkUnixXId.c

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)/tkMacOSXInit.c $(MAC_OSX_DIR)/tkMacOSXKeyboard.c \
	$(MAC_OSX_DIR)/tkMacOSXKeyEvent.c \
	$(MAC_OSX_DIR)/tkMacOSXMenu.c \
	$(MAC_OSX_DIR)/tkMacOSXMenubutton.c $(MAC_OSX_DIR)/tkMacOSXMenus.c \
	$(MAC_OSX_DIR)/tkMacOSXMouseEvent.c $(MAC_OSX_DIR)/tkMacOSXNotify.c \
	$(MAC_OSX_DIR)/tkMacOSXRegion.c $(MAC_OSX_DIR)/tkMacOSXScrlbr.c \
	$(MAC_OSX_DIR)/tkMacOSXServices.c \
	$(MAC_OSX_DIR)/tkMacOSXServices.c $(MAC_OSX_DIR)/tkMacOSXSysTray.c \
	$(MAC_OSX_DIR)/tkMacOSXSend.c $(MAC_OSX_DIR)/tkMacOSXSubwindows.c \
	$(MAC_OSX_DIR)/tkMacOSXTest.c $(MAC_OSX_DIR)/tkMacOSXWindowEvent.c \
	$(MAC_OSX_DIR)/tkMacOSXWm.c $(MAC_OSX_DIR)/tkMacOSXXStubs.c \
	$(GENERIC_DIR)/tkFileFilter.c $(GENERIC_DIR)/tkMacWinMenu.c \
	$(GENERIC_DIR)/tkPointer.c $(UNIX_DIR)/tkUnix3d.c \
	$(UNIX_DIR)/tkUnixScale.c $(XLIB_DIR)/xcolors.c $(XLIB_DIR)/xdraw.c \
	$(XLIB_DIR)/xgc.c $(XLIB_DIR)/ximage.c $(XLIB_DIR)/xutil.c \
628
629
630
631
632
633
634
635
636


637
638
639
640
641
642
643
628
629
630
631
632
633
634


635
636
637
638
639
640
641
642
643







-
-
+
+







# 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_STUB_LIB_FILE} ${TCL_STUB_LIB_SPEC} @TK_BUILD_LIB_SPEC@ \
		$(WISH_LIBS) $(CC_SEARCH_FLAGS) -o $(TKTEST_EXE)
	${CC} ${CFLAGS} ${LDFLAGS} $(TKTEST_OBJS) @TK_BUILD_LIB_SPEC@ $(WISH_LIBS) \
		${TK_STUB_LIB_FILE} ${TCL_STUB_LIB_SPEC} $(CC_SEARCH_FLAGS) -o $(TKTEST_EXE)

# # FIXME: This xttest rule seems to be broken in a number of ways.  It should
# # use CC_SEARCH_FLAGS, it does not include the shared lib location logic from
# # tktest, and it is not clear where this test.o object file comes from.
#
# xttest: test.o tkTest.o tkSquare.o $(TK_LIB_FILE) ${TK_STUB_LIB_FILE}
# 	${CC} ${CFLAGS} ${LDFLAGS} test.o tkTest.o tkSquare.o \
726
727
728
729
730
731
732
733

734
735
736
737

738
739

740
741


742
743
744
745
746
747
748
749
750
751


752
753
754
755
756
757
758
726
727
728
729
730
731
732

733
734
735
736

737
738

739
740

741
742
743
744
745
746
747
748
749
750


751
752
753
754
755
756
757
758
759







-
+



-
+

-
+

-
+
+








-
-
+
+







	@if test "x$(TK_SHARED_BUILD)" = "x1"; then \
	    echo "Creating package index $(PKG_INDEX)"; \
	    rm -f "$(PKG_INDEX)"; \
	    (\
	    echo "if {[catch {package present Tcl 8.6-}]} return";\
	    relative=`echo | awk '{ORS=" "; split("$(TK_PKG_DIR)",a,"/"); for (f in a) {print ".."}}'`;\
	    if test "x$(DLL_INSTALL_DIR)" != "x$(BIN_INSTALL_DIR)"; then \
	    echo "package ifneeded Tk $(MAJOR_VERSION).$(MINOR_VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir $${relative}$(TK_LIB_FILE)]] Tk]";\
	    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 \
	    fi; \
	    echo "package ifneeded Tk $(MAJOR_VERSION).$(MINOR_VERSION)$(PATCH_LEVEL) [list package require -exact tk $(MAJOR_VERSION).$(MINOR_VERSION)$(PATCH_LEVEL)]"\
	    ) > "$(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";\
	    $(INSTALL_LIBRARY) "../win/libtk${MAJOR_VERSION}${MINOR_VERSION}.dll.a" "$(LIB_INSTALL_DIR)";\
	    chmod 555 "$(LIB_INSTALL_DIR)/libtk${MAJOR_VERSION}${MINOR_VERSION}.dll.a";\
	fi
	@echo "Installing ${WISH_EXE} as $(BIN_INSTALL_DIR)/wish$(VERSION)${EXE_SUFFIX}"
	@$(INSTALL_PROGRAM) ${WISH_EXE} "$(BIN_INSTALL_DIR)/wish$(VERSION)${EXE_SUFFIX}"
	@echo "Installing tkConfig.sh to $(CONFIG_INSTALL_DIR)/"
	@$(INSTALL_DATA) tkConfig.sh "$(CONFIG_INSTALL_DIR)/tkConfig.sh"
	@if test "$(STUB_LIB_FILE)" != "" ; then \
	    echo "Installing $(STUB_LIB_FILE) to $(LIB_INSTALL_DIR)/"; \
1189
1190
1191
1192
1193
1194
1195
1196

1197
1198
1199
1200
1201
1202
1203
1190
1191
1192
1193
1194
1195
1196

1197
1198
1199
1200
1201
1202
1203
1204







-
+







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

1256
1257
1258
1259
1260
1261
1262






1263
1264
1265
1266
1267
1268
1269
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276







+
+
+
+
+
+








tkUnixSelect.o: $(UNIX_DIR)/tkUnixSelect.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tkUnixSelect.c

tkUnixSend.o: $(UNIX_DIR)/tkUnixSend.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tkUnixSend.c

tkUnixSysNotify.o: $(UNIX_DIR)/tkUnixSysNotify.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tkUnixSysNotify.c

tkUnixSysTray.o: $(UNIX_DIR)/tkUnixSysTray.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tkUnixSysTray.c

tkUnixWm.o: $(UNIX_DIR)/tkUnixWm.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tkUnixWm.c

tkUnixXId.o: $(UNIX_DIR)/tkUnixXId.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tkUnixXId.c

tkMacOSXBitmap.o: $(MAC_OSX_DIR)/tkMacOSXBitmap.c
1362
1363
1364
1365
1366
1367
1368



1369
1370
1371
1372
1373
1374
1375
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385







+
+
+








tkMacOSXWm.o: $(MAC_OSX_DIR)/tkMacOSXWm.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXWm.c

tkMacOSXXStubs.o: $(MAC_OSX_DIR)/tkMacOSXXStubs.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXXStubs.c

tkMacOSXSysTray.o: $(MAC_OSX_DIR)/tkMacOSXSysTray.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXSysTray.c

tkFileFilter.o: $(GENERIC_DIR)/tkFileFilter.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkFileFilter.c

tkMacWinMenu.o: $(GENERIC_DIR)/tkMacWinMenu.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkMacWinMenu.c

tkPointer.o: $(GENERIC_DIR)/tkPointer.c
1459
1460
1461
1462
1463
1464
1465
1466

1467
1468
1469
1470
1471
1472
1473
1469
1470
1471
1472
1473
1474
1475

1476
1477
1478
1479
1480
1481
1482
1483







-
+







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

1557
1558
1559
1560
1561
1562
1563
1564

1565
1566
1567
1568
1569
1570
1571
1567
1568
1569
1570
1571
1572
1573

1574
1575
1576
1577
1578
1579
1580
1581







-
+







	mkdir -p RPMS/i386
	rpmbuild -bb THIS.TK.SPEC
	mv RPMS/i386/*.rpm .
	rm -rf RPMS THIS.TK.SPEC

#
# Target to create a proper Tk distribution from information in the
# master source directory.  DISTDIR must be defined to indicate where
# source directory.  DISTDIR must be defined to indicate where
# 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)
1580
1581
1582
1583
1584
1585
1586
1587

1588
1589
1590

1591
1592
1593
1594
1595
1596
1597
1590
1591
1592
1593
1594
1595
1596

1597
1598
1599

1600
1601
1602
1603
1604
1605
1606
1607







-
+


-
+







$(UNIX_DIR)/tkConfig.h.in: $(MAC_OSX_DIR)/configure
	cd $(MAC_OSX_DIR); autoheader; touch $@

$(TOP_DIR)/manifest.uuid:
	printf "git." >$(TOP_DIR)/manifest.uuid
	git rev-parse HEAD >>$(TOP_DIR)/manifest.uuid

dist:	$(UNIX_DIR)/configure $(UNIX_DIR)/tkConfig.h.in $(UNIX_DIR)/tk.pc.in $(MAC_OSX_DIR)/configure $(TOP_DIR)/doc/man.macros $(TOP_DIR)/manifest.uuid genstubs
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) $(TOP_DIR)/manifest.uuid $(DISTDIR)
	$(DIST_INSTALL_DATA) $(UNIX_DIR)/*.c $(UNIX_DIR)/*.h $(DISTDIR)/unix
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(UNIX_DIR)/Makefile.in $(DISTDIR)/unix
	$(DIST_INSTALL_DATA) $(UNIX_DIR)/configure.ac $(UNIX_DIR)/tk.spec \
		$(UNIX_DIR)/aclocal.m4 $(UNIX_DIR)/tcl.m4 \
		$(UNIX_DIR)/tkConfig.sh.in $(UNIX_DIR)/install-sh \
		$(UNIX_DIR)/README $(UNIX_DIR)/installManPage \
		$(UNIX_DIR)/tkConfig.h.in $(UNIX_DIR)/tk.pc.in $(DISTDIR)/unix
1696
1697
1698
1699
1700
1701
1702



1703
1704
1705
1706
1707
1708
1709
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722







+
+
+







		$(TOP_DIR)/doc/man.macros $(DISTDIR)/doc
	$(INSTALL_DATA_DIR) $(DISTDIR)/tests
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(TEST_DIR)/*.{test,tcl} \
		$(TEST_DIR)/README $(TEST_DIR)/*.{gif,png,ppm,xbm} \
		$(TEST_DIR)/option.file* $(DISTDIR)/tests
	$(INSTALL_DATA_DIR) $(DISTDIR)/tests/ttk
	$(DIST_INSTALL_DATA) $(TEST_DIR)/ttk/*.{test,tcl} $(DISTDIR)/tests/ttk
	cp -p $(TOP_DIR)/.travis.yml $(DISTDIR)
	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.

1
2
3

4
5
6

7
8
9
10
11
12
13
14
15
16

17


18
19
20
21
22
23
24

25
26
27
28
29
30
31
32
33








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


47
48
49


50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65




66
67
68
69
70

















71
72
73

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

97
98





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

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
1
2

3
4
5

6
7
8
9
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
25

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










47
48



49
50







51









52
53
54
55





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

75
76
77
78
79
80
81
82
83







84
85
86
87
88
89
90
91
92


93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108

109
110
111
112




















113
114
115
116
117
118
119


-
+


-
+










+
-
+
+






-
+









+
+
+
+
+
+
+
+



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


-
+








-
-
-
-
-
-
-








+
-
-
+
+
+
+
+











-
+



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







#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for tk 8.7.
# Generated by GNU Autoconf 2.70 for tk 8.7.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
# Copyright (C) 1992-1996, 1998-2017, 2020 Free Software Foundation, Inc.
#
#
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##

# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
as_nop=:
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
if test ${ZSH_VERSION+y} && (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
else $as_nop
  case `(set -o) 2>/dev/null` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;
esac
fi



# Reset variables that may have inherited troublesome values from
# the environment.

# IFS needs to be set, to space, tab, and newline, in precisely that order.
# (If _AS_PATH_WALK were called with IFS unset, it would have the
# side effect of setting IFS to empty, thus disabling word splitting.)
# Quoting is to prevent editors from complaining about space-tab.
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 --'
IFS=" ""	$as_nl"

elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
  as_echo='printf %s\n'
  as_echo_n='printf %s'
PS1='$ '
PS2='> '
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
PS4='+ '
      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

# Ensure predictable behavior from utilities with locale-dependent output.
LC_ALL=C
export LC_ALL
    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
LANGUAGE=C
export LANGUAGE

# We cannot yet rely on "unset" to work, but we need these variables
# to be unset--not just set to an empty or harmless value--now, to
# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh).  This construct
# also avoids known problems related to "unset" and subshell syntax
# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
do eval test \${$as_var+y} \
  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
done

# Ensure that fds 0, 1, and 2 are open.
if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
if (exec 3>&2)            ; then :; else exec 2>/dev/null; fi

# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
if ${PATH_SEPARATOR+false} :; then
  PATH_SEPARATOR=:
  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
      PATH_SEPARATOR=';'
  }
fi


# IFS
# We need space, tab and new line, in precisely that order.  Quoting is
# there to prevent editors from complaining about space-tab.
# (If _AS_PATH_WALK were called with IFS unset, it would disable word
# splitting by setting IFS to empty value.)
IFS=" ""	$as_nl"

# Find who we are.  Look in the path if we contain no directory separator.
as_myself=
case $0 in #((
  *[\\/]* ) as_myself=$0 ;;
  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    test -r "$as_dir$0" && as_myself=$as_dir$0 && break
  done
IFS=$as_save_IFS

     ;;
esac
# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
  as_myself=$0
fi
if test ! -f "$as_myself"; then
  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
  exit 1
fi

# Unset variables that we do not need and which cause bugs (e.g. in
# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
# suppresses any "Segmentation fault" message there.  '((' could
# trigger a bug in pdksh 5.2.14.
for as_var in BASH_ENV ENV MAIL MAILPATH
do eval test x\${$as_var+set} = xset \
  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
done
PS1='$ '
PS2='> '
PS4='+ '

# NLS nuisances.
LC_ALL=C
export LC_ALL
LANGUAGE=C
export LANGUAGE

# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH

# Use a proper internal environment variable to ensure we don't fall
  # into an infinite loop, continuously re-executing ourselves.
  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
    _as_can_reexec=no; export _as_can_reexec;
    # We cannot yet assume a decent shell, so we have to provide a
# neutralization value for shells without unset; and this also
148
149
150
151
152
153
154
155
156


157
158
159
160
161



162
163
164
165
166
167
168

169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188


189
190

191
192
193


194
195
196
197
198
199
200


201
202

203
204
205


206
207

208
209
210
211
212

213




214
215
216
217
218
219

220
221


222
223


224
225
226
227
228
229
230





231
232



233
234

235

236
237
238


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

257
258
259
260
261
262
263
264
265







266
267

268
269
270
271
272
273
274
127
128
129
130
131
132
133


134
135
136
137
138
139

140
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168

169
170
171

172
173
174
175
176
177
178
179
180
181
182
183

184
185
186

187
188
189

190
191
192

193
194
195
196
197
198
199

200
201
202
203
204
205
206
207
208

209
210

211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
226
227


228
229
230
231

232

233
234
235

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

255
256
257
258






259
260
261
262
263
264
265
266

267
268
269
270
271
272
273
274







-
-
+
+




-
+
+
+






-
+



















-
+
+

-
+



+
+






-
+
+

-
+


-
+
+

-
+





+
-
+
+
+
+





-
+

-
+
+

-
+
+







+
+
+
+
+
-
-
+
+
+

-
+
-
+


-
+
+

















-
+



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

-
+







  *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
printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
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 :
  as_bourne_compatible="as_nop=:
if test \${ZSH_VERSION+y} && (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
else \$as_nop
  case \`(set -o) 2>/dev/null\` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;
esac
fi
"
  as_required="as_fn_return () { (exit \$1); }
as_fn_success () { as_fn_return 0; }
as_fn_failure () { as_fn_return 1; }
as_fn_ret_success () { return 0; }
as_fn_ret_failure () { return 1; }

exitcode=0
as_fn_success || { exitcode=1; echo as_fn_success failed.; }
as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
if ( set x; as_fn_ret_success y && test x = \"\$1\" )
then :

else
else \$as_nop
  exitcode=1; echo positional parameters were not saved.
fi
test x\$exitcode = x0 || exit 1
blah=\$(echo \$(echo blah))
test x\"\$blah\" = xblah || 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 :
  if (eval "$as_required") 2>/dev/null
then :
  as_have_required=yes
else
else $as_nop
  as_have_required=no
fi
  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null
then :

else
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
  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
	     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 :
		    as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 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 :
		   if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null
then :
  break 2
fi
fi
	   done;;
       esac
  as_found=false
done
IFS=$as_save_IFS
if $as_found
then :

else $as_nop
$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 :
  if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
	      as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null
then :
  CONFIG_SHELL=$SHELL as_have_required=yes
fi; }
fi
IFS=$as_save_IFS
fi


      if test "x$CONFIG_SHELL" != x; then :
      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
printf "%s\n" "$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."
    if test x$as_have_required = xno
then :
  printf "%s\n" "$0: This script requires a shell more modern than all"
  printf "%s\n" "$0: the shells that I found on your system."
  if test ${ZSH_VERSION+y} ; then
    printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should"
    printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later."
  else
    $as_echo "$0: Please tell [email protected] about your system,
    printf "%s\n" "$0: Please tell [email protected] 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
286
287
288
289
290
291
292

293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310








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

326
327
328
329
330
331
332
333
334

335
336
337
338
339
340
341
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333

334
335
336
337
338
339
340
341
342

343
344
345
346
347
348
349
350







+


















+
+
+
+
+
+
+
+














-
+








-
+







# ---------------
# 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_nop
# ---------
# Do nothing but, unlike ":", preserve the value of $?.
as_fn_nop ()
{
  return $?
}
as_nop=as_fn_nop

# 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=`printf "%s\n" "$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" |
printf "%s\n" X"$as_dir" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q
366
367
368
369
370
371
372
373


374
375
376
377
378

379
380
381
382
383
384
385
386
387
388
389
390


391
392
393
394
395

396
397
398
399
400
401








402
403
404
405
406
407
408
409
410
411
412
413

414
415

416
417
418
419
420
421
422
375
376
377
378
379
380
381

382
383
384
385
386
387

388
389
390
391
392
393
394
395
396
397
398
399

400
401
402
403
404
405

406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431

432
433

434
435
436
437
438
439
440
441







-
+
+




-
+











-
+
+




-
+






+
+
+
+
+
+
+
+











-
+

-
+







} # 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 :
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
else $as_nop
  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 :
if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
then :
  eval 'as_fn_arith ()
  {
    as_val=$(( $* ))
  }'
else
else $as_nop
  as_fn_arith ()
  {
    as_val=`expr "$@" || test $? -eq 1`
  }
fi # as_fn_arith

# as_fn_nop
# ---------
# Do nothing but, unlike ":", preserve the value of $?.
as_fn_nop ()
{
  return $?
}
as_nop=as_fn_nop

# 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
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
  fi
  $as_echo "$as_me: error: $2" >&2
  printf "%s\n" "$as_me: error: $2" >&2
  as_fn_exit $as_status
} # as_fn_error

if expr a : '\(a\)' >/dev/null 2>&1 &&
   test "X`expr 00001 : '.*\(...\)'`" = X001; then
  as_expr=expr
else
435
436
437
438
439
440
441
442

443
444
445
446
447
448
449
454
455
456
457
458
459
460

461
462
463
464
465
466
467
468







-
+







  as_dirname=false
fi

as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
	 X"$0" : 'X\(//\)$' \| \
	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X/"$0" |
printf "%s\n" X/"$0" |
    sed '/^.*\/\([^/][^/]*\)\/*$/{
	    s//\1/
	    q
	  }
	  /^X\/\(\/\/\)$/{
	    s//\1/
	    q
479
480
481
482
483
484
485
486

487
488
489
490
491
492
493
494
495
496
497
498
499




500
501
502
503
504
505
506
507
508
509
510
511







512
513
514
515
516
517
518
498
499
500
501
502
503
504

505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548







-
+













+
+
+
+












+
+
+
+
+
+
+







      N
      :loop
      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
      t loop
      s/-\n.*//
    ' >$as_me.lineno &&
  chmod +x "$as_me.lineno" ||
    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
    { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }

  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
  # already done that, so ensure we don't try to do so again and fall
  # in an infinite loop.  This has already happened in practice.
  _as_can_reexec=no; export _as_can_reexec
  # Don't try to exec as it changes $[0], causing all sort of problems
  # (the dirname of $[0] is not the place where we might find the
  # original and so on.  Autoconf is especially sensitive to this).
  . "./$as_me.lineno"
  # Exit status is that of the last command.
  exit
}


# Determine whether it's possible to make 'echo' print without a newline.
# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
# for compatibility with existing Makefiles.
ECHO_C= ECHO_N= ECHO_T=
case `echo -n x` in #(((((
-n*)
  case `echo 'xy\c'` in
  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
  xy)  ECHO_C='\c';;
  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
       ECHO_T='	';;
  esac;;
*)
  ECHO_N='-n';;
esac

# For backward compatibility with old third-party macros, we provide
# the shell variables $as_echo and $as_echo_n.  New code should use
# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
as_echo='printf %s\n'
as_echo_n='printf %s'


rm -f conf$$ conf$$.exe conf$$.file
if test -d conf$$.dir; then
  rm -f conf$$.dir/conf$$.file
else
  rm -f conf$$.dir
  mkdir conf$$.dir 2>/dev/null
580
581
582
583
584
585
586
587
588
589



590
591

592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616









617
618
619
620

621
622
623
624
625
626
627
610
611
612
613
614
615
616



617
618
619
620

621



622





623
624



625
626



627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653







-
-
-
+
+
+

-
+
-
-
-

-
-
-
-
-


-
-
-


-
-
-






+
+
+
+
+
+
+
+
+




+







PACKAGE_VERSION='8.7'
PACKAGE_STRING='tk 8.7'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''

# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#include <stddef.h>
#ifdef HAVE_STDIO_H
# include <stdio.h>
#endif
#ifdef HAVE_SYS_STAT_H
#ifdef HAVE_STDLIB_H
# include <sys/stat.h>
#endif
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
#  include <stdlib.h>
# endif
#endif
#ifdef HAVE_STRING_H
# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
#  include <memory.h>
# endif
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
#endif
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif"

ac_header_c_list=
ac_subst_vars='LTLIBOBJS
REZ_FLAGS
REZ
APP_RSRC_FILE
LIB_RSRC_FILE
WISH_RSRC_FILE
TK_RSRC_FILE
663
664
665
666
667
668
669



670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687

688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726



727
728
729
730
731
732
733







+
+
+


















+









-
-
-







TK_VERSION
TK_DEMO_DIR
DEMO_DIR
UNIX_FONT_OBJS
XFT_LIBS
XFT_CFLAGS
XMKMF
EGREP
GREP
CPP
LDFLAGS_DEFAULT
CFLAGS_DEFAULT
INSTALL_STUB_LIB
DLL_INSTALL_DIR
INSTALL_LIB
MAKE_STUB_LIB
MAKE_LIB
SHLIB_SUFFIX
SHLIB_CFLAGS
SHLIB_LD_LIBS
TK_SHLIB_LD_EXTRAS
TCL_SHLIB_LD_EXTRAS
SHLIB_LD
STLIB_LD
LD_SEARCH_FLAGS
CC_SEARCH_FLAGS
LDFLAGS_OPTIMIZE
LDFLAGS_DEBUG
CFLAGS_NOLTO
CFLAGS_WARNING
CFLAGS_OPTIMIZE
CFLAGS_DEBUG
LDAIX_SRC
PLAT_SRCS
PLAT_OBJS
DL_OBJS
DL_LIBS
TCL_LIBS
EGREP
GREP
CPP
LIBOBJS
AR
RANLIB
SHARED_BUILD
OBJEXT
EXEEXT
ac_ct_CC
736
737
738
739
740
741
742

743
744
745
746
747
748
749
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777







+







pdfdir
dvidir
htmldir
infodir
docdir
oldincludedir
includedir
runstatedir
localstatedir
sharedstatedir
sysconfdir
datadir
datarootdir
libexecdir
sbindir
825
826
827
828
829
830
831

832
833
834
835
836
837
838
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867







+







sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
datarootdir='${prefix}/share'
datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
infodir='${datarootdir}/info'
htmldir='${docdir}'
dvidir='${docdir}'
pdfdir='${docdir}'
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
883
884
885
886
887
888
889


890
891
892
893
894
895
896







-
-








  case $ac_option in
  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
  *=)   ac_optarg= ;;
  *)    ac_optarg=yes ;;
  esac

  # Accept the important Cygnus configure options, so we can diagnose typos.

  case $ac_dashdash$ac_option in
  --)
    ac_dashdash=yes ;;

  -bindir | --bindir | --bindi | --bind | --bin | --bi)
    ac_prev=bindir ;;
  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
896
897
898
899
900
901
902
903

904
905

906
907
908
909
910
911
912
923
924
925
926
927
928
929

930
931

932
933
934
935
936
937
938
939







-
+

-
+







  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
    datarootdir=$ac_optarg ;;

  -disable-* | --disable-*)
    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid feature name: $ac_useropt"
      as_fn_error $? "invalid feature name: \`$ac_useropt'"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    ac_useropt=`printf "%s\n" "$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
922
923
924
925
926
927
928
929

930
931

932
933
934
935
936
937
938
949
950
951
952
953
954
955

956
957

958
959
960
961
962
963
964
965







-
+

-
+







  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
    dvidir=$ac_optarg ;;

  -enable-* | --enable-*)
    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid feature name: $ac_useropt"
      as_fn_error $? "invalid feature name: \`$ac_useropt'"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
    case $ac_user_opts in
      *"
"enable_$ac_useropt"
"*) ;;
      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac
1076
1077
1078
1079
1080
1081
1082









1083
1084
1085
1086
1087
1088
1089
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125







+
+
+
+
+
+
+
+
+







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

  -runstatedir | --runstatedir | --runstatedi | --runstated \
  | --runstate | --runstat | --runsta | --runst | --runs \
  | --run | --ru | --r)
    ac_prev=runstatedir ;;
  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
  | --run=* | --ru=* | --r=*)
    runstatedir=$ac_optarg ;;

  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
    ac_prev=sbindir ;;
  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
  | --sbi=* | --sb=*)
    sbindir=$ac_optarg ;;

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







-
+

-
+













-
+

-
+







  -version | --version | --versio | --versi | --vers | -V)
    ac_init_version=: ;;

  -with-* | --with-*)
    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid package name: $ac_useropt"
      as_fn_error $? "invalid package name: \`$ac_useropt'"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
    case $ac_user_opts in
      *"
"with_$ac_useropt"
"*) ;;
      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac
    eval with_$ac_useropt=\$ac_optarg ;;

  -without-* | --without-*)
    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid package name: $ac_useropt"
      as_fn_error $? "invalid package name: \`$ac_useropt'"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
    case $ac_user_opts in
      *"
"with_$ac_useropt"
"*) ;;
      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac
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
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







-
+

-
+















-
+







-
+







      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
    esac
    eval $ac_envvar=\$ac_optarg
    export $ac_envvar ;;

  *)
    # FIXME: should be removed in autoconf 3.0.
    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
    printf "%s\n" "$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
      printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2
    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
    ;;

  esac
done

if test -n "$ac_prev"; then
  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
  as_fn_error $? "missing argument to $ac_option"
fi

if test -n "$ac_unrecognized_opts"; then
  case $enable_option_checking in
    no) ;;
    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
    *)     printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
  esac
fi

# Check all directory arguments for consistency.
for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
		datadir sysconfdir sharedstatedir localstatedir includedir \
		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
		libdir localedir mandir
		libdir localedir mandir runstatedir
do
  eval ac_val=\$$ac_var
  # Remove trailing slashes.
  case $ac_val in
    */ )
      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
      eval $ac_var=\$ac_val;;
1270
1271
1272
1273
1274
1275
1276
1277

1278
1279
1280
1281
1282
1283
1284
1306
1307
1308
1309
1310
1311
1312

1313
1314
1315
1316
1317
1318
1319
1320







-
+







  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" |
printf "%s\n" X"$as_myself" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q
1367
1368
1369
1370
1371
1372
1373

1374
1375
1376
1377
1378
1379
1380
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417







+







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]
  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
  --libdir=DIR            object code libraries [EPREFIX/lib]
  --includedir=DIR        C header files [PREFIX/include]
  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
  --infodir=DIR           info documentation [DATAROOTDIR/info]
  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
1426
1427
1428
1429
1430
1431
1432
1433

1434
1435
1436
1437
1438
1439
1440
1441
1463
1464
1465
1466
1467
1468
1469

1470

1471
1472
1473
1474
1475
1476
1477







-
+
-







                          (default: off)

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-encoding         encoding for configuration values (default:
  --with-encoding         encoding for configuration values (default: utf-8)
                          iso8859-1)
  --with-x                use the X Window System

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>
1460
1461
1462
1463
1464
1465
1466
1467

1468
1469

1470
1471
1472
1473
1474
1475
1476
1496
1497
1498
1499
1500
1501
1502

1503
1504

1505
1506
1507
1508
1509
1510
1511
1512







-
+

-
+







      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
      continue
    ac_builddir=.

case "$ac_dir" in
.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
*)
  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
  ac_dir_suffix=/`printf "%s\n" "$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_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
  case $ac_top_builddir_sub in
  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
  esac ;;
esac
ac_abs_top_builddir=$ac_pwd
ac_abs_builddir=$ac_pwd$ac_dir_suffix
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
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







-
+
+







-
+









-
+

-
+
















-
+






-
+







-
+



-
+
+

-
-
+
+















-
+






-
+







-
+






+
-
+

-
-
+
+














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







-
-
-
-
-
+
+
+
+
+
+





-
+
+

-
+


-
+


-
-
+
+










-
-
-
-
-
+
+
+
+
+
+







-
+
-
-

-
-
+
-
-
-
-

















-
+






-
+
+

-
+


-
+



-
-
+
+



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








-
-
-
-
-
+
+
+
+
+
+





-
+







-
+
+




-
+







-
+
+

-
+


-
+

-
+


-
-
+
+



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





-
+

-
+







    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
    ac_top_srcdir=$ac_top_build_prefix$srcdir
    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
esac
ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix

    cd "$ac_dir" || { ac_status=$?; continue; }
    # Check for guested configure.
    # Check for configure.gnu first; this name is used for a wrapper for
    # Metaconfig's "Configure" on case-insensitive file systems.
    if test -f "$ac_srcdir/configure.gnu"; then
      echo &&
      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
    elif test -f "$ac_srcdir/configure"; then
      echo &&
      $SHELL "$ac_srcdir/configure" --help=recursive
    else
      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
      printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2
    fi || ac_status=$?
    cd "$ac_pwd" || { ac_status=$?; break; }
  done
fi

test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
  cat <<\_ACEOF
tk configure 8.7
generated by GNU Autoconf 2.69
generated by GNU Autoconf 2.70

Copyright (C) 2012 Free Software Foundation, Inc.
Copyright (C) 2020 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
  exit
fi

## ------------------------ ##
## Autoconf initialization. ##
## ------------------------ ##

# ac_fn_c_try_compile LINENO
# --------------------------
# Try to compile conftest.$ac_ext, and return whether this succeeded.
ac_fn_c_try_compile ()
{
  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
  rm -f conftest.$ac_objext
  rm -f conftest.$ac_objext conftest.beam
  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
printf "%s\n" "$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
  printf "%s\n" "$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 :
       } && test -s conftest.$ac_objext
then :
  ac_retval=0
else
  $as_echo "$as_me: failed program was:" >&5
else $as_nop
  printf "%s\n" "$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_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
  rm -f conftest.$ac_objext conftest.beam 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
printf "%s\n" "$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
  printf "%s\n" "$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 :
then :
  ac_retval=0
else
  $as_echo "$as_me: failed program was:" >&5
else $as_nop
  printf "%s\n" "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

	ac_retval=1
fi
  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
  # interfere with the next link command; also delete a directory that is
  # left behind by Apple's compiler.  We do this before executing the actions.
  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
  as_fn_set_status $ac_retval

} # ac_fn_c_try_link

# 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_check_header_mongrel LINENO HEADER VAR INCLUDES
# -------------------------------------------------------
# Tests whether HEADER exists, giving a warning if it cannot be compiled using
# the include files in INCLUDES and setting the cache variable VAR
# accordingly.
ac_fn_c_check_header_mongrel ()
{
  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
  if eval \${$3+:} false; then :
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
if eval \${$3+:} false; then :
  $as_echo_n "(cached) " >&6
fi
eval ac_res=\$$3
	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
else
  # Is the header compilable?
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
$as_echo_n "checking $2 usability... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$4
#include <$2>
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
  ac_header_compiler=yes
else
  ac_header_compiler=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
$as_echo "$ac_header_compiler" >&6; }

# Is the header present?
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
$as_echo_n "checking $2 presence... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <$2>
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :
  ac_header_preproc=yes
else
  ac_header_preproc=no
fi
rm -f conftest.err conftest.i conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
$as_echo "$ac_header_preproc" >&6; }

# So?  What about this header?
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
  yes:no: )
    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
    ;;
  no:yes:* )
    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
    ;;
esac
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
if eval \${$3+:} false; then :
  $as_echo_n "(cached) " >&6
else
  eval "$3=\$ac_header_compiler"
fi
eval ac_res=\$$3
	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
fi
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

} # ac_fn_c_check_header_mongrel

# ac_fn_c_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_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
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
printf %s "checking for $2... " >&6; }
if eval test \${$3+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$4
#include <$2>
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  eval "$3=yes"
else
else $as_nop
  eval "$3=no"
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
eval ac_res=\$$3
	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
printf "%s\n" "$ac_res" >&6; }
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

} # ac_fn_c_check_header_compile

# ac_fn_c_check_func LINENO FUNC VAR
# ----------------------------------
# Tests whether FUNC exists, setting the cache variable VAR accordingly
ac_fn_c_check_func ()
{
  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
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
printf %s "checking for $2... " >&6; }
if eval test \${$3+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
#define $2 innocuous_$2

/* System header to define __stub macros and hopefully few prototypes,
    which can conflict with char $2 (); below.
   which can conflict with char $2 (); below.  */
    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
    <limits.h> exists even on freestanding compilers.  */

#ifdef __STDC__
# include <limits.h>
#include <limits.h>
#else
# include <assert.h>
#endif

#undef $2

/* Override any GCC internal prototype to avoid an error.
   Use char because int might match the return type of a GCC
   builtin and then its argument prototype would still apply.  */
#ifdef __cplusplus
extern "C"
#endif
char $2 ();
/* The GNU C library defines this for functions which it implements
    to always fail with ENOSYS.  Some functions are actually named
    something starting with __ and the normal name is an alias.  */
#if defined __stub_$2 || defined __stub___$2
choke me
#endif

int
main ()
main (void)
{
return $2 ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  eval "$3=yes"
else
else $as_nop
  eval "$3=no"
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
fi
eval ac_res=\$$3
	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
printf "%s\n" "$ac_res" >&6; }
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

} # ac_fn_c_check_func

# ac_fn_c_try_run LINENO
# ----------------------
# Try to run 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\""
printf "%s\n" "$ac_try_echo"; } >&5
  (eval "$ac_link") 2>&5
  ac_status=$?
  printf "%s\n" "$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\""
printf "%s\n" "$ac_try_echo"; } >&5
  (eval "$ac_try") 2>&5
  ac_status=$?
  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; }
then :
  ac_retval=0
else $as_nop
  printf "%s\n" "$as_me: program exited with status $ac_status" >&5
       printf "%s\n" "$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_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\""
printf "%s\n" "$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
  printf "%s\n" "$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_nop
  printf "%s\n" "$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_check_type LINENO TYPE VAR INCLUDES
# -------------------------------------------
# Tests whether TYPE exists after having included INCLUDES, setting cache
# variable VAR accordingly.
ac_fn_c_check_type ()
{
  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
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
printf %s "checking for $2... " >&6; }
if eval test \${$3+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  eval "$3=no"
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$4
int
main ()
main (void)
{
if (sizeof ($2))
	 return 0;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$4
int
main ()
main (void)
{
if (sizeof (($2)))
	    return 0;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :

else
else $as_nop
  eval "$3=yes"
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
eval ac_res=\$$3
	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
printf "%s\n" "$ac_res" >&6; }
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

} # ac_fn_c_check_type
ac_configure_args_raw=
for ac_arg
do
  case $ac_arg in
  *\'*)
    ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
  esac
  as_fn_append ac_configure_args_raw " '$ac_arg'"
done

case $ac_configure_args_raw in
  *$as_nl*)
    ac_safe_unquote= ;;
  *)
    ac_unsafe_z='|&;<>()$`\\"*?[ ''	' # This string ends in space, tab.
    ac_unsafe_a="$ac_unsafe_z#~"
    ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g"
    ac_configure_args_raw=`      printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;;
esac

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 tk $as_me 8.7, which was
generated by GNU Autoconf 2.69.  Invocation command line was
generated by GNU Autoconf 2.70.  Invocation command line was

  $ $0 $@
  $ $0$ac_configure_args_raw

_ACEOF
exec 5>>config.log
{
cat <<_ASUNAME
## --------- ##
## Platform. ##
1962
1963
1964
1965
1966
1967
1968

1969
1970





1971
1972
1973
1974
1975
1976
1977
1936
1937
1938
1939
1940
1941
1942
1943


1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955







+
-
-
+
+
+
+
+








_ASUNAME

as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    $as_echo "PATH: $as_dir"
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    printf "%s\n" "PATH: $as_dir"
  done
IFS=$as_save_IFS

} >&5

cat >&5 <<_ACEOF

1998
1999
2000
2001
2002
2003
2004
2005

2006
2007
2008
2009
2010
2011
2012
1976
1977
1978
1979
1980
1981
1982

1983
1984
1985
1986
1987
1988
1989
1990







-
+







  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=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
    esac
    case $ac_pass in
    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
    2)
      as_fn_append ac_configure_args1 " '$ac_arg'"
      if test $ac_must_keep_next = true; then
	ac_must_keep_next=false # Got value, back to normal.
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
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







+
+




-
+










-
-
+
+








# When interrupted or exit'd, cleanup temporary files, and complete
# config.log.  We remove comments because anyway the quotes in there
# would cause problems or look ugly.
# WARNING: Use '\'' to represent an apostrophe within the trap.
# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
trap 'exit_status=$?
  # Sanitize IFS.
  IFS=" ""	$as_nl"
  # Save into config.log some information that might help in debugging.
  {
    echo

    $as_echo "## ---------------- ##
    printf "%s\n" "## ---------------- ##
## Cache variables. ##
## ---------------- ##"
    echo
    # The following way of writing the cache mishandles newlines in values,
(
  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
    eval ac_val=\$$ac_var
    case $ac_val in #(
    *${as_nl}*)
      case $ac_var in #(
      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
      *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
printf "%s\n" "$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
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
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







-
+







-
+

-
+




-
+







-
+

-
+





-
+







-
-
+
+













-
+



-
-
+
-

-
-
+
-

-
-
+
-

-
-
+
-

-
-
+
-

-
-
+
-




-
-

-
-
+
-
-
-
-

-
+
-

-
+
-

+
-
+

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


-
-
+
+









-
-
+
+






-
-
+
+



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










-
-
+
+


-
-
+
+








-
-
+
+


-
-
+
+


-
-
-
-
+
+
+
+





-
+









-
-
-
-
-
+
+
+
+
+
+







      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
      ;;
    esac |
    sort
)
    echo

    $as_echo "## ----------------- ##
    printf "%s\n" "## ----------------- ##
## Output variables. ##
## ----------------- ##"
    echo
    for ac_var in $ac_subst_vars
    do
      eval ac_val=\$$ac_var
      case $ac_val in
      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
      *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
      esac
      $as_echo "$ac_var='\''$ac_val'\''"
      printf "%s\n" "$ac_var='\''$ac_val'\''"
    done | sort
    echo

    if test -n "$ac_subst_files"; then
      $as_echo "## ------------------- ##
      printf "%s\n" "## ------------------- ##
## File substitutions. ##
## ------------------- ##"
      echo
      for ac_var in $ac_subst_files
      do
	eval ac_val=\$$ac_var
	case $ac_val in
	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
	*\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
	esac
	$as_echo "$ac_var='\''$ac_val'\''"
	printf "%s\n" "$ac_var='\''$ac_val'\''"
      done | sort
      echo
    fi

    if test -s confdefs.h; then
      $as_echo "## ----------- ##
      printf "%s\n" "## ----------- ##
## confdefs.h. ##
## ----------- ##"
      echo
      cat confdefs.h
      echo
    fi
    test "$ac_signal" != 0 &&
      $as_echo "$as_me: caught signal $ac_signal"
    $as_echo "$as_me: exit $exit_status"
      printf "%s\n" "$as_me: caught signal $ac_signal"
    printf "%s\n" "$as_me: exit $exit_status"
  } >&5
  rm -f core *.core core.conftest.* &&
    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
    exit $exit_status
' 0
for ac_signal in 1 2 13 15; do
  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
done
ac_signal=0

# confdefs.h avoids OS command line length limits that DEFS can exceed.
rm -f -r conftest* confdefs.h

$as_echo "/* confdefs.h */" > confdefs.h
printf "%s\n" "/* confdefs.h */" > confdefs.h

# Predefined preprocessor variables.

cat >>confdefs.h <<_ACEOF
#define PACKAGE_NAME "$PACKAGE_NAME"
printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_VERSION "$PACKAGE_VERSION"
printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_STRING "$PACKAGE_STRING"
printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_URL "$PACKAGE_URL"
printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h
_ACEOF


# Let the site file select an alternate cache file if it wants to.
# Prefer an explicitly selected file to automatically selected ones.
ac_site_file1=NONE
ac_site_file2=NONE
if test -n "$CONFIG_SITE"; then
  # We do not want a PATH search for config.site.
  case $CONFIG_SITE in #((
  ac_site_files="$CONFIG_SITE"
    -*)  ac_site_file1=./$CONFIG_SITE;;
    */*) ac_site_file1=$CONFIG_SITE;;
    *)   ac_site_file1=./$CONFIG_SITE;;
  esac
elif test "x$prefix" != xNONE; then
  ac_site_file1=$prefix/share/config.site
  ac_site_files="$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
  ac_site_files="$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"
for ac_site_file in $ac_site_files
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;}
  case $ac_site_file in #(
  */*) :
     ;; #(
  *) :
    ac_site_file=./$ac_site_file ;;
esac
  if test -f "$ac_site_file" && test -r "$ac_site_file"; then
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;}
    sed 's/^/| /' "$ac_site_file" >&5
    . "$ac_site_file" \
      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
      || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
printf "%s\n" "$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;}
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
printf "%s\n" "$as_me: loading cache $cache_file" >&6;}
    case $cache_file in
      [\\/]* | ?:[\\/]* ) . "$cache_file";;
      *)                      . "./$cache_file";;
    esac
  fi
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
$as_echo "$as_me: creating cache $cache_file" >&6;}
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
printf "%s\n" "$as_me: creating cache $cache_file" >&6;}
  >$cache_file
fi

# Test code for whether the C compiler supports C89 (global declarations)
ac_c_conftest_c89_globals='
/* Does the compiler advertise C89 conformance?
   Do not test the value of __STDC__, because some compilers set it to 0
   while being otherwise adequately conformant. */
#if !defined __STDC__
# error "Compiler does not advertise C89 conformance"
#endif

#include <stddef.h>
#include <stdarg.h>
struct stat;
/* Most of the following tests are stolen from RCS 5.7 src/conf.sh.  */
struct buf { int x; };
struct buf * (*rcsopen) (struct buf *, struct stat *, int);
static char *e (p, i)
     char **p;
     int i;
{
  return p[i];
}
static char *f (char * (*g) (char **, int), char **p, ...)
{
  char *s;
  va_list v;
  va_start (v,p);
  s = g (p, va_arg (v,int));
  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 do not provoke an error unfortunately, instead are silently treated
   as an "x".  The following induces an error, until -std is added to get
   proper ANSI mode.  Curiously \x00 != x always comes out true, for an
   array size at least.  It is necessary to write \x00 == 0 to get something
   that is true only with -std.  */
int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1];

/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
   inside strings and character constants.  */
#define FOO(x) '\''x'\''
int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1];

int test (int i, double x);
struct s1 {int (*f) (int a);};
struct s2 {int (*f) (double a);};
int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int),
               int, int);'

# Test code for whether the C compiler supports C89 (body of main).
ac_c_conftest_c89_main='
ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]);
'

# Test code for whether the C compiler supports C99 (global declarations)
ac_c_conftest_c99_globals='
// Does the compiler advertise C99 conformance?
#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
# error "Compiler does not advertise C99 conformance"
#endif

#include <stdbool.h>
extern int puts (const char *);
extern int printf (const char *, ...);
extern int dprintf (int, const char *, ...);
extern void *malloc (size_t);

// Check varargs macros.  These examples are taken from C99 6.10.3.5.
// dprintf is used instead of fprintf to avoid needing to declare
// FILE and stderr.
#define debug(...) dprintf (2, __VA_ARGS__)
#define showlist(...) puts (#__VA_ARGS__)
#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
static void
test_varargs_macros (void)
{
  int x = 1234;
  int y = 5678;
  debug ("Flag");
  debug ("X = %d\n", x);
  showlist (The first, second, and third items.);
  report (x>y, "x is %d but y is %d", x, y);
}

// Check long long types.
#define BIG64 18446744073709551615ull
#define BIG32 4294967295ul
#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
#if !BIG_OK
  #error "your preprocessor is broken"
#endif
#if BIG_OK
#else
  #error "your preprocessor is broken"
#endif
static long long int bignum = -9223372036854775807LL;
static unsigned long long int ubignum = BIG64;

struct incomplete_array
{
  int datasize;
  double data[];
};

struct named_init {
  int number;
  const wchar_t *name;
  double average;
};

typedef const char *ccp;

static inline int
test_restrict (ccp restrict text)
{
  // See if C++-style comments work.
  // Iterate through items via the restricted pointer.
  // Also check for declarations in for loops.
  for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i)
    continue;
  return 0;
}

// Check varargs and va_copy.
static bool
test_varargs (const char *format, ...)
{
  va_list args;
  va_start (args, format);
  va_list args_copy;
  va_copy (args_copy, args);

  const char *str = "";
  int number = 0;
  float fnumber = 0;

  while (*format)
    {
      switch (*format++)
	{
	case '\''s'\'': // string
	  str = va_arg (args_copy, const char *);
	  break;
	case '\''d'\'': // int
	  number = va_arg (args_copy, int);
	  break;
	case '\''f'\'': // float
	  fnumber = va_arg (args_copy, double);
	  break;
	default:
	  break;
	}
    }
  va_end (args_copy);
  va_end (args);

  return *str && number && fnumber;
}
'

# Test code for whether the C compiler supports C99 (body of main).
ac_c_conftest_c99_main='
  // Check bool.
  _Bool success = false;
  success |= (argc != 0);

  // Check restrict.
  if (test_restrict ("String literal") == 0)
    success = true;
  char *restrict newvar = "Another string";

  // Check varargs.
  success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234);
  test_varargs_macros ();

  // Check flexible array members.
  struct incomplete_array *ia =
    malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
  ia->datasize = 10;
  for (int i = 0; i < ia->datasize; ++i)
    ia->data[i] = i * 1.234;

  // Check named initializers.
  struct named_init ni = {
    .number = 34,
    .name = L"Test wide string",
    .average = 543.34343,
  };

  ni.number = 58;

  int dynamic_array[ni.number];
  dynamic_array[0] = argv[0][0];
  dynamic_array[ni.number - 1] = 543;

  // work around unused variable warnings
  ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\''
	 || dynamic_array[ni.number - 1] != 543);
'

# Test code for whether the C compiler supports C11 (global declarations)
ac_c_conftest_c11_globals='
// Does the compiler advertise C11 conformance?
#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L
# error "Compiler does not advertise C11 conformance"
#endif

// Check _Alignas.
char _Alignas (double) aligned_as_double;
char _Alignas (0) no_special_alignment;
extern char aligned_as_int;
char _Alignas (0) _Alignas (int) aligned_as_int;

// Check _Alignof.
enum
{
  int_alignment = _Alignof (int),
  int_array_alignment = _Alignof (int[100]),
  char_alignment = _Alignof (char)
};
_Static_assert (0 < -_Alignof (int), "_Alignof is signed");

// Check _Noreturn.
int _Noreturn does_not_return (void) { for (;;) continue; }

// Check _Static_assert.
struct test_static_assert
{
  int x;
  _Static_assert (sizeof (int) <= sizeof (long int),
                  "_Static_assert does not work in struct");
  long int y;
};

// Check UTF-8 literals.
#define u8 syntax error!
char const utf8_literal[] = u8"happens to be ASCII" "another string";

// Check duplicate typedefs.
typedef long *long_ptr;
typedef long int *long_ptr;
typedef long_ptr long_ptr;

// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1.
struct anonymous
{
  union {
    struct { int i; int j; };
    struct { int k; long int l; } w;
  };
  int m;
} v1;
'

# Test code for whether the C compiler supports C11 (body of main).
ac_c_conftest_c11_main='
  _Static_assert ((offsetof (struct anonymous, i)
		   == offsetof (struct anonymous, w.k)),
		  "Anonymous union alignment botch");
  v1.i = 2;
  v1.w.k = 5;
  ok |= v1.i != 5;
'

# Test code for whether the C compiler supports C11 (complete).
ac_c_conftest_c11_program="${ac_c_conftest_c89_globals}
${ac_c_conftest_c99_globals}
${ac_c_conftest_c11_globals}

int
main (int argc, char **argv)
{
  int ok = 0;
  ${ac_c_conftest_c89_main}
  ${ac_c_conftest_c99_main}
  ${ac_c_conftest_c11_main}
  return ok;
}
"

# Test code for whether the C compiler supports C99 (complete).
ac_c_conftest_c99_program="${ac_c_conftest_c89_globals}
${ac_c_conftest_c99_globals}

int
main (int argc, char **argv)
{
  int ok = 0;
  ${ac_c_conftest_c89_main}
  ${ac_c_conftest_c99_main}
  return ok;
}
"

# Test code for whether the C compiler supports C89 (complete).
ac_c_conftest_c89_program="${ac_c_conftest_c89_globals}

int
main (int argc, char **argv)
{
  int ok = 0;
  ${ac_c_conftest_c89_main}
  return ok;
}
"

as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H"
as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H"
as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H"
as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H"
as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H"
as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H"
as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H"
as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H"
as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H"
as_fn_append ac_header_c_list " sys/time.h sys_time_h HAVE_SYS_TIME_H"
# Check that the precious variables saved in the cache have kept the same
# value.
ac_cache_corrupted=false
for ac_var in $ac_precious_vars; do
  eval ac_old_set=\$ac_cv_env_${ac_var}_set
  eval ac_new_set=\$ac_env_${ac_var}_set
  eval ac_old_val=\$ac_cv_env_${ac_var}_value
  eval ac_new_val=\$ac_env_${ac_var}_value
  case $ac_old_set,$ac_new_set in
    set,)
      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
printf "%s\n" "$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;}
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
printf "%s\n" "$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;}
	  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
printf "%s\n" "$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;}
	  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
printf "%s\n" "$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;}
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
printf "%s\n" "$as_me:   former value:  \`$ac_old_val'" >&2;}
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
printf "%s\n" "$as_me:   current value: \`$ac_new_val'" >&2;}
      fi;;
  esac
  # Pass precious variables to config.status.
  if test "$ac_new_set" = set; then
    case $ac_new_val in
    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
    *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
    *) ac_arg=$ac_var=$ac_new_val ;;
    esac
    case " $ac_configure_args " in
      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
    esac
  fi
done
if $ac_cache_corrupted; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;}
  as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file'
	    and start over" "$LINENO" 5
fi
## -------------------- ##
## Main body of script. ##
## -------------------- ##

ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
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
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







-
+
+



-
-
-
-
-
+
+
+
+
+
+







-
-
+
+







    #

    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 :
if test ${with_tcl+y}
then :
  withval=$with_tcl; with_tclconfig="${withval}"
fi

	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl configuration" >&5
$as_echo_n "checking for Tcl configuration... " >&6; }
	if ${ac_cv_c_tclconfig+:} false; then :
  $as_echo_n "(cached) " >&6
else
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Tcl configuration" >&5
printf %s "checking for Tcl configuration... " >&6; }
	if test ${ac_cv_c_tclconfig+y}
then :
  printf %s "(cached) " >&6
else $as_nop


	    # 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;}
			    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5
printf "%s\n" "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;}
			    with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
			fi ;;
		esac
		if test -f "${with_tclconfig}/tclConfig.sh" ; then
		    ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
		else
		    as_fn_error $? "${with_tclconfig} directory doesn't contain tclConfig.sh" "$LINENO" 5
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
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







-
-
+
+




-
-
+
+


-
-
+
+


-
-
+
+








	if test x"${ac_cv_c_tclconfig}" = x ; then
	    TCL_BIN_DIR="# no Tcl configs found"
	    as_fn_error $? "Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh" "$LINENO" 5
	else
	    no_tcl=
	    TCL_BIN_DIR="${ac_cv_c_tclconfig}"
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5
$as_echo "found ${TCL_BIN_DIR}/tclConfig.sh" >&6; }
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5
printf "%s\n" "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; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for existence of ${TCL_BIN_DIR}/tclConfig.sh" >&5
printf %s "checking for existence of ${TCL_BIN_DIR}/tclConfig.sh... " >&6; }

    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5
$as_echo "loading" >&6; }
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: loading" >&5
printf "%s\n" "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; }
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: could not find ${TCL_BIN_DIR}/tclConfig.sh" >&5
printf "%s\n" "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
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
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







-
-
-
-
-
+
+
+
+
+
+



















-
-
+
+



-
-
+
+




-
-
+
+

-
-
+
+







if test "${TCL_MINOR_VERSION}" -lt 6 ; then
    as_fn_error $? "${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 8.6+
Found config for Tcl ${TCL_VERSION}" "$LINENO" 5
fi
fi


    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tclsh" >&5
$as_echo_n "checking for tclsh... " >&6; }
    if ${ac_cv_path_tclsh+:} false; then :
  $as_echo_n "(cached) " >&6
else
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tclsh" >&5
printf %s "checking for tclsh... " >&6; }
    if test ${ac_cv_path_tclsh+y}
then :
  printf %s "(cached) " >&6
else $as_nop

	search_path=`echo ${PATH} | sed -e 's/:/ /g'`
	for dir in $search_path ; do
	    for j in `ls -r $dir/tclsh[8-9]* 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; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $TCLSH_PROG" >&5
printf "%s\n" "$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; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: No tclsh found on PATH" >&5
printf "%s\n" "No tclsh found on PATH" >&6; }
    fi



    { $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; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tclsh in Tcl build directory" >&5
printf %s "checking for tclsh in Tcl build directory... " >&6; }
    BUILD_TCLSH="${TCL_BIN_DIR}"/tclsh
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_TCLSH" >&5
$as_echo "$BUILD_TCLSH" >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $BUILD_TCLSH" >&5
printf "%s\n" "$BUILD_TCLSH" >&6; }



#------------------------------------------------------------------------
# Handle the --prefix=... option
#------------------------------------------------------------------------

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







-
-
+
+

-
+
+

-
+



-
-
+
+

-
-
+
+

-
+
+





-
+



-
-
+
+

-
-
+
+





-
-
+
+


-
-
+
+

-
+
+





-
+



-
-
+
+













+
+
+
+
+
+
+
+
+









-
-
-
-
-
+
+
+
+
+
+







+
-
+
+
+
+

-
+

-
+










-
-
+
+

-
-
+
+








-
-
-
-
-
+
+
+
+
+
+







+
-
+
+
+
+

-
+

-
+










-
-
+
+

-
-
+
+







-
-
+
+












-
-
-
-
-
+
+
+
+
+
+







+
-
+
+
+
+

-
+

-
+










-
-
+
+

-
-
+
+








-
-
-
-
-
+
+
+
+
+
+








+
-
+
+
+
+

-
-
+
+




-
+















-
+






-
-
+
+

-
-
+
+










-
-
-
-
-
+
+
+
+
+
+







+
-
+
+
+
+

-
+

-
+










-
-
+
+

-
-
+
+












-
-
-
-
-
+
+
+
+
+
+







+
-
+
+
+
+

-
+

-
+










-
-
+
+

-
-
+
+











-
-
+
+




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





-
-
+
+




-
+


-
+






-
+









-
+







-
+











-
-
-
+
+
+




















-
+


-
-
+
+
+
















-
+















-
+


-
-
-
-
+
+
+
+
+


-
-
+
+


-
-
-
+
+
+

-
-
-
-
+
+
+
+




-
-
+
+






-
+


-
-
+
+
+













-
-
-
+
+
+




-
-
+
+








-
+











-
-
+
+







-
+


-
+







-
+


-
+






-
-
-
+
+
+





-
-
+
+



-
-
-
-
-
+
+
+
+
+
+




-
+













-
+


-
-
+
+
+








-
-
+
+


-
-
+
+





-
-
+
+


-
-
-
-
-
+
+
+
+
+
+




-
+









-
+
+

-
+


-
+



-
-
+
+
+
+





-
+

-
-
-
-
-
+
+
+
+
+
+








-
+






-
+
+

-
+





-
+






-
+
+

-
+






-
+






-
+
+


-
+

-
+

-
+


-
-
-
+
+
+














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




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





-
+
+


-
+







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

-
+
+
+
+
+
+
+
+
+
+










-
-
-
-
-
+
+
+
+
+
+






-
-
+
+



-
+
+


-
+




-
-
+
+







TK_SRC_DIR="`cd "$srcdir"/..; pwd`"

#------------------------------------------------------------------------
# Compress and/or soft link the manpages?
#------------------------------------------------------------------------


    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use symlinks for manpages" >&5
$as_echo_n "checking whether to use symlinks for manpages... " >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to use symlinks for manpages" >&5
printf %s "checking whether to use symlinks for manpages... " >&6; }
    # Check whether --enable-man-symlinks was given.
if test "${enable_man_symlinks+set}" = set; then :
if test ${enable_man_symlinks+y}
then :
  enableval=$enable_man_symlinks; test "$enableval" != "no" && MAN_FLAGS="$MAN_FLAGS --symlinks"
else
else $as_nop
  enableval="no"
fi

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5
$as_echo "$enableval" >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5
printf "%s\n" "$enableval" >&6; }

    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to compress the manpages" >&5
$as_echo_n "checking whether to compress the manpages... " >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to compress the manpages" >&5
printf %s "checking whether to compress the manpages... " >&6; }
    # Check whether --enable-man-compression was given.
if test "${enable_man_compression+set}" = set; then :
if test ${enable_man_compression+y}
then :
  enableval=$enable_man_compression; case $enableval in
	    yes) as_fn_error $? "missing argument to --enable-man-compression" "$LINENO" 5;;
	    no)  ;;
	    *)   MAN_FLAGS="$MAN_FLAGS --compress $enableval";;
	esac
else
else $as_nop
  enableval="no"
fi

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5
$as_echo "$enableval" >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5
printf "%s\n" "$enableval" >&6; }
    if test "$enableval" != "no"; then
	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for compressed file suffix" >&5
$as_echo_n "checking for compressed file suffix... " >&6; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for compressed file suffix" >&5
printf %s "checking for compressed file suffix... " >&6; }
	touch TeST
	$enableval TeST
	Z=`ls TeST* | sed 's/^....//'`
	rm -f TeST*
	MAN_FLAGS="$MAN_FLAGS --extension $Z"
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $Z" >&5
$as_echo "$Z" >&6; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $Z" >&5
printf "%s\n" "$Z" >&6; }
    fi

    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to add a package name suffix for the manpages" >&5
$as_echo_n "checking whether to add a package name suffix for the manpages... " >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to add a package name suffix for the manpages" >&5
printf %s "checking whether to add a package name suffix for the manpages... " >&6; }
    # Check whether --enable-man-suffix was given.
if test "${enable_man_suffix+set}" = set; then :
if test ${enable_man_suffix+y}
then :
  enableval=$enable_man_suffix; case $enableval in
	    yes) enableval="tk" MAN_FLAGS="$MAN_FLAGS --suffix $enableval";;
	    no)  ;;
	    *)   MAN_FLAGS="$MAN_FLAGS --suffix $enableval";;
	esac
else
else $as_nop
  enableval="no"
fi

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5
$as_echo "$enableval" >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5
printf "%s\n" "$enableval" >&6; }




#------------------------------------------------------------------------
# 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_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
if test -n "$ac_tool_prefix"; then
  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
set dummy ${ac_tool_prefix}gcc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CC+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_CC+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_CC="${ac_tool_prefix}gcc"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
$as_echo "$CC" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
printf "%s\n" "$CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi


fi
if test -z "$ac_cv_prog_CC"; then
  ac_ct_CC=$CC
  # Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_CC+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_ac_ct_CC+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_CC="gcc"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
$as_echo "$ac_ct_CC" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
printf "%s\n" "$ac_ct_CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "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;}
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    CC=$ac_ct_CC
  fi
else
  CC="$ac_cv_prog_CC"
fi

if test -z "$CC"; then
          if test -n "$ac_tool_prefix"; then
    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
set dummy ${ac_tool_prefix}cc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CC+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_CC+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_CC="${ac_tool_prefix}cc"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
$as_echo "$CC" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
printf "%s\n" "$CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi


  fi
fi
if test -z "$CC"; then
  # Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CC+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_CC+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
       ac_prog_rejected=yes
       continue
     fi
    ac_cv_prog_CC="cc"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

if test $ac_prog_rejected = yes; then
  # We found a bogon in the path, so make sure we never use it.
  set dummy $ac_cv_prog_CC
  shift
  if test $# != 0; then
    # We chose a different compiler from the bogus one.
    # However, it has the same basename, so the bogon will be chosen
    # first if we set CC to just the basename; use the full file name.
    shift
    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
    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; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
printf "%s\n" "$CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi


fi
if test -z "$CC"; then
  if test -n "$ac_tool_prefix"; then
  for ac_prog in cl.exe
  do
    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CC+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_CC+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
$as_echo "$CC" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
printf "%s\n" "$CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi


    test -n "$CC" && break
  done
fi
if test -z "$CC"; then
  ac_ct_CC=$CC
  for ac_prog in cl.exe
do
  # Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_CC+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_ac_ct_CC+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_CC="$ac_prog"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
$as_echo "$ac_ct_CC" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
printf "%s\n" "$ac_ct_CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "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;}
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    CC=$ac_ct_CC
  fi
fi

fi
if test -z "$CC"; then
  if test -n "$ac_tool_prefix"; then
  # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args.
set dummy ${ac_tool_prefix}clang; ac_word=$2
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_CC+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_CC="${ac_tool_prefix}clang"
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
printf "%s\n" "$CC" >&6; }
else
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi


fi
if test -z "$ac_cv_prog_CC"; then
  ac_ct_CC=$CC
  # Extract the first word of "clang", so it can be a program name with args.
set dummy clang; ac_word=$2
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_ac_ct_CC+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_CC="clang"
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
printf "%s\n" "$ac_ct_CC" >&6; }
else
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi

  if test "x$ac_ct_CC" = x; then
    CC=""
  else
    case $cross_compiling:$ac_tool_warned in
yes:)
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    CC=$ac_ct_CC
  fi
else
  CC="$ac_cv_prog_CC"
fi

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;}
test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "no acceptable C compiler found in \$PATH
See \`config.log' for more details" "$LINENO" 5; }

# Provide some information about the compiler.
$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
set X $ac_compile
ac_compiler=$2
for ac_option in --version -v -V -qversion; do
for ac_option in --version -v -V -qversion -version; 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
printf "%s\n" "$ac_try_echo"; } >&5
  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
  ac_status=$?
  if test -s conftest.err; then
    sed '10a\
... rest of stderr output deleted ...
         10q' conftest.err >conftest.er1
    cat conftest.er1 >&5
  fi
  rm -f conftest.er1 conftest.err
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }
done

cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
main (void)
{

  ;
  return 0;
}
_ACEOF
ac_clean_files_save=$ac_clean_files
ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
# Try to create an executable without -o first, disregard a.out.
# It will help us diagnose broken compilers, and finding out an intuition
# of exeext.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
$as_echo_n "checking whether the C compiler works... " >&6; }
ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
printf %s "checking whether the C compiler works... " >&6; }
ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'`

# The possible output files:
ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"

ac_rmfiles=
for ac_file in $ac_files
do
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
  esac
done
rm -f $ac_rmfiles

if { { ac_try="$ac_link_default"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
printf "%s\n" "$ac_try_echo"; } >&5
  (eval "$ac_link_default") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; then :
  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }
then :
  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
# in a Makefile.  We should not override ac_cv_exeext if it was cached,
# so that the user can short-circuit this test for compilers unknown to
# Autoconf.
for ac_file in $ac_files ''
do
  test -f "$ac_file" || continue
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
	;;
    [ab].out )
	# We found the default executable, but exeext='' is most
	# certainly right.
	break;;
    *.* )
	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
	if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no;
	then :; else
	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
	fi
	# We set ac_cv_exeext here because the later test for it is not
	# safe: cross compilers may not add the suffix if given an `-o'
	# argument, so we may need to know it at that point already.
	# Even if this section looks crufty: it has the advantage of
	# actually working.
	break;;
    * )
	break;;
  esac
done
test "$ac_cv_exeext" = no && ac_cv_exeext=

else
else $as_nop
  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
if test -z "$ac_file"
then :
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
printf "%s\n" "$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;}
{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
printf "%s\n" "$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; }
else $as_nop
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
$as_echo_n "checking for C compiler default output file name... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
$as_echo "$ac_file" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
printf %s "checking for C compiler default output file name... " >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
printf "%s\n" "$ac_file" >&6; }
ac_exeext=$ac_cv_exeext

rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
ac_clean_files=$ac_clean_files_save
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
$as_echo_n "checking for suffix of executables... " >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
printf %s "checking for suffix of executables... " >&6; }
if { { ac_try="$ac_link"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
printf "%s\n" "$ac_try_echo"; } >&5
  (eval "$ac_link") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; then :
  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }
then :
  # If both `conftest.exe' and `conftest' are `present' (well, observable)
# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
# work properly (i.e., refer to `conftest.exe'), while it won't with
# `rm'.
for ac_file in conftest.exe conftest conftest.*; do
  test -f "$ac_file" || continue
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
	  break;;
    * ) break;;
  esac
done
else
  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
else $as_nop
  { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of executables: cannot compile and link
See \`config.log' for more details" "$LINENO" 5; }
fi
rm -f conftest conftest$ac_cv_exeext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
$as_echo "$ac_cv_exeext" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
printf "%s\n" "$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 ()
main (void)
{
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; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
printf %s "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
printf "%s\n" "$ac_try_echo"; } >&5
  (eval "$ac_link") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  printf "%s\n" "$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
printf "%s\n" "$ac_try_echo"; } >&5
  (eval "$ac_try") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  printf "%s\n" "$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.
	{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error 77 "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; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
printf "%s\n" "$cross_compiling" >&6; }

rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
ac_clean_files=$ac_clean_files_save
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
$as_echo_n "checking for suffix of object files... " >&6; }
if ${ac_cv_objext+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
printf %s "checking for suffix of object files... " >&6; }
if test ${ac_cv_objext+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
main (void)
{

  ;
  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
printf "%s\n" "$ac_try_echo"; } >&5
  (eval "$ac_compile") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; then :
  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }
then :
  for ac_file in conftest.o conftest.obj conftest.*; do
  test -f "$ac_file" || continue;
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
       break;;
  esac
done
else
  $as_echo "$as_me: failed program was:" >&5
else $as_nop
  printf "%s\n" "$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;}
{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of object files: cannot compile
See \`config.log' for more details" "$LINENO" 5; }
fi
rm -f conftest.$ac_cv_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
$as_echo "$ac_cv_objext" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
printf "%s\n" "$ac_cv_objext" >&6; }
OBJEXT=$ac_cv_objext
ac_objext=$OBJEXT
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
if ${ac_cv_c_compiler_gnu+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5
printf %s "checking whether the compiler supports GNU C... " >&6; }
if test ${ac_cv_c_compiler_gnu+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
main (void)
{
#ifndef __GNUC__
       choke me
#endif

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  ac_compiler_gnu=yes
else
else $as_nop
  ac_compiler_gnu=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam 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; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; }
ac_compiler_gnu=$ac_cv_c_compiler_gnu

if test $ac_compiler_gnu = yes; then
  GCC=yes
else
  GCC=
fi
ac_test_CFLAGS=${CFLAGS+set}
ac_test_CFLAGS=${CFLAGS+y}
ac_save_CFLAGS=$CFLAGS
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
$as_echo_n "checking whether $CC accepts -g... " >&6; }
if ${ac_cv_prog_cc_g+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
printf %s "checking whether $CC accepts -g... " >&6; }
if test ${ac_cv_prog_cc_g+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  ac_save_c_werror_flag=$ac_c_werror_flag
   ac_c_werror_flag=yes
   ac_cv_prog_cc_g=no
   CFLAGS="-g"
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_prog_cc_g=yes
else
else $as_nop
  CFLAGS=""
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :

else
else $as_nop
  ac_c_werror_flag=$ac_save_c_werror_flag
	 CFLAGS="-g"
	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_prog_cc_g=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   ac_c_werror_flag=$ac_save_c_werror_flag
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
$as_echo "$ac_cv_prog_cc_g" >&6; }
if test "$ac_test_CFLAGS" = set; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
printf "%s\n" "$ac_cv_prog_cc_g" >&6; }
if test $ac_test_CFLAGS; then
  CFLAGS=$ac_save_CFLAGS
elif test $ac_cv_prog_cc_g = yes; then
  if test "$GCC" = yes; then
    CFLAGS="-g -O2"
  else
    CFLAGS="-g"
  fi
else
  if test "$GCC" = yes; then
    CFLAGS="-O2"
  else
    CFLAGS=
  fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
if ${ac_cv_prog_cc_c89+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5
printf %s "checking for $CC option to enable C11 features... " >&6; }
if test ${ac_cv_prog_cc_c11+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  ac_cv_prog_cc_c11=no
ac_save_CC=$CC
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$ac_c_conftest_c11_program
_ACEOF
for ac_arg in '' -std=gnu11
do
  CC="$ac_save_CC $ac_arg"
  if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_prog_cc_c11=$ac_arg
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam
  test "x$ac_cv_prog_cc_c11" != "xno" && break
done
rm -f conftest.$ac_ext
CC=$ac_save_CC

fi
# AC_CACHE_VAL
ac_prog_cc_stdc_options=
case "x$ac_cv_prog_cc_c11" in #(
  x) :
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
printf "%s\n" "none needed" >&6; } ;; #(
  xno) :
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
printf "%s\n" "unsupported" >&6; } ;; #(
  *) :
    ac_prog_cc_stdc_options=" $ac_cv_prog_cc_c11"
    CC="$CC$ac_prog_cc_stdc_options"
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5
printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } ;;
esac
if test "x$ac_cv_prog_cc_c11" != xno
then :
  ac_prog_cc_stdc=c11
		 ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11
else $as_nop
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5
printf %s "checking for $CC option to enable C99 features... " >&6; }
if test ${ac_cv_prog_cc_c99+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  ac_cv_prog_cc_c99=no
ac_save_CC=$CC
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$ac_c_conftest_c89_program
_ACEOF
for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc1x -qlanglvl=extc99
do
  CC="$ac_save_CC $ac_arg"
  if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_prog_cc_c99=$ac_arg
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam
  test "x$ac_cv_prog_cc_c99" != "xno" && break
done
rm -f conftest.$ac_ext
CC=$ac_save_CC

fi
# AC_CACHE_VAL
ac_prog_cc_stdc_options=
case "x$ac_cv_prog_cc_c99" in #(
  x) :
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
printf "%s\n" "none needed" >&6; } ;; #(
  xno) :
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
printf "%s\n" "unsupported" >&6; } ;; #(
  *) :
    ac_prog_cc_stdc_options=" $ac_cv_prog_cc_c99"
    CC="$CC$ac_prog_cc_stdc_options"
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } ;;
esac
if test "x$ac_cv_prog_cc_c99" != xno
then :
  ac_prog_cc_stdc=c99
		    ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
else $as_nop
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5
printf %s "checking for $CC option to enable C89 features... " >&6; }
if test ${ac_cv_prog_cc_c89+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  ac_cv_prog_cc_c89=no
ac_save_CC=$CC
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <stdarg.h>
#include <stdio.h>
struct stat;
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
struct buf { int x; };
FILE * (*rcsopen) (struct buf *, struct stat *, int);
static char *e (p, i)
     char **p;
     int i;
{
  return p[i];
}
static char *f (char * (*g) (char **, int), char **p, ...)
{
  char *s;
  va_list v;
  va_start (v,p);
  s = g (p, va_arg (v,int));
  va_end (v);
  return s;
}

$ac_c_conftest_c89_program
/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
   function prototypes and stuff, but not '\xHH' hex character constants.
   These don't provoke an error unfortunately, instead are silently treated
   as 'x'.  The following induces an error, until -std is added to get
   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
   array size at least.  It's necessary to write '\x00'==0 to get something
   that's true only with -std.  */
int osf4_cc_array ['\x00' == 0 ? 1 : -1];

/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
   inside strings and character constants.  */
#define FOO(x) 'x'
int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];

int test (int i, double x);
struct s1 {int (*f) (int a);};
struct s2 {int (*f) (double a);};
int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
int argc;
char **argv;
int
main ()
{
return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
  ;
  return 0;
}
_ACEOF
for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
do
  CC="$ac_save_CC $ac_arg"
  if ac_fn_c_try_compile "$LINENO"; then :
  if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_prog_cc_c89=$ac_arg
fi
rm -f core conftest.err conftest.$ac_objext
rm -f core conftest.err conftest.$ac_objext conftest.beam
  test "x$ac_cv_prog_cc_c89" != "xno" && break
done
rm -f conftest.$ac_ext
CC=$ac_save_CC

fi
# AC_CACHE_VAL
ac_prog_cc_stdc_options=
case "x$ac_cv_prog_cc_c89" in
  x)
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
$as_echo "none needed" >&6; } ;;
  xno)
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
$as_echo "unsupported" >&6; } ;;
  *)
    CC="$CC $ac_cv_prog_cc_c89"
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
case "x$ac_cv_prog_cc_c89" in #(
  x) :
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
printf "%s\n" "none needed" >&6; } ;; #(
  xno) :
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
printf "%s\n" "unsupported" >&6; } ;; #(
  *) :
    ac_prog_cc_stdc_options=" $ac_cv_prog_cc_c89"
    CC="$CC$ac_prog_cc_stdc_options"
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } ;;
esac
if test "x$ac_cv_prog_cc_c89" != xno; then :
if test "x$ac_cv_prog_cc_c89" != xno
then :
  ac_prog_cc_stdc=c89
		       ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
else $as_nop
  ac_prog_cc_stdc=no
		       ac_cv_prog_cc_stdc=no
fi

fi

fi

ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
$as_echo_n "checking for inline... " >&6; }
if ${ac_cv_c_inline+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
printf %s "checking for inline... " >&6; }
if test ${ac_cv_c_inline+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  ac_cv_c_inline=no
for ac_kw in inline __inline__ __inline; do
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#ifndef __cplusplus
typedef int foo_t;
static $ac_kw foo_t static_foo () {return 0; }
$ac_kw foo_t foo () {return 0; }
static $ac_kw foo_t static_foo (void) {return 0; }
$ac_kw foo_t foo (void) {return 0; }
#endif

_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_c_inline=$ac_kw
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam 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; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
printf "%s\n" "$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;;
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465






3466
3467
3468
3469
3470
3471
3472

3473
3474
3475
3476
3477
3478
3479


3480
3481

3482
3483
3484

3485
3486
3487
3488


3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501


3502
3503
3504
3505
3506
3507
3508
3509

3510
3511
3512
3513
3514

3515
3516
3517
3518
3519
3520
3521


3522
3523


3524
3525

3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539


3540
3541
3542
3543


3544
3545
3546

3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565






3566
3567
3568
3569
3570
3571
3572

3573




3574
3575

3576
3577

3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589


3590
3591
3592


3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605






3606
3607
3608
3609
3610
3611
3612

3613




3614
3615

3616
3617

3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629


3630
3631
3632


3633
3634
3635
3636
3637
3638
3639
3640
3641


3642
3643
3644
3645
3646
3647
3648
3649
3650

3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669

3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683

3684
3685
3686
3687


3688
3689
3690
3691


3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709

3710
3711
3712
3713
3714
3715
3716

3717
3718
3719

3720
3721
3722
3723
3724



3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962

3963
3964
3965
3966
3967

3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026

4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052


4053
4054


4055
4056

4057
4058
4059
4060
4061


4062
4063
4064
4065
4066


4067
4068


4069
4070

4071
4072
4073
4074
4075


4076
4077


4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088






4089
4090
4091
4092
4093
4094
4095
4096
4097

4098
4099
4100
4101
4102
4103
4104


4105
4106

4107
4108
4109

4110
4111
4112
4113
4114
4115




4116
4117
4118

4119
4120
4121

4122
4123
4124
4125
4126
4127
4128
4129


4130
4131


4132
4133

4134
4135
4136
4137
4138


4139
4140
4141
4142
4143
4144
4145
4146
4147
4148






4149
4150
4151
4152
4153
4154
4155
4156


4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170


4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181






4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195

4196
4197
4198
4199
4200
4201
4202


4203
4204

4205
4206
4207

4208
4209
4210
4211
4212
4213




4214
4215

4216
4217
4218
4219
4220
4221
4222
3959
3960
3961
3962
3963
3964
3965





3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977

3978
3979
3980
3981
3982
3983
3984

3985
3986
3987

3988
3989
3990

3991
3992
3993


3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007

4008
4009
4010
4011
4012
4013
4014
4015


4016

4017
4018
4019

4020
4021
4022
4023
4024
4025


4026
4027
4028

4029
4030
4031

4032
4033
4034
4035








4036


4037
4038
4039
4040


4041
4042
4043
4044

4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059





4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073

4074
4075
4076
4077
4078

4079
4080

4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091


4092
4093
4094


4095
4096
4097
4098
4099
4100
4101
4102
4103
4104





4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118

4119
4120
4121
4122
4123

4124
4125

4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136


4137
4138
4139


4140
4141
4142
4143
4144
4145
4146
4147
4148


4149
4150
4151
4152
4153
4154
4155
4156
4157
4158

4159



















4160
4161













4162




4163
4164




4165
4166


















4167







4168



4169





4170
4171
4172












































4173















































































4174
4175















































4176











4177





4178
4179











4180




















4181












4182





4183



4184























































4185
4186
4187


















4188
4189
4190
4191


4192
4193
4194

4195
4196
4197

4198
4199
4200
4201


4202
4203
4204
4205
4206


4207
4208
4209

4210
4211
4212

4213
4214
4215
4216


4217
4218
4219

4220
4221
4222
4223
4224
4225
4226
4227





4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241

4242
4243
4244
4245
4246
4247
4248

4249
4250
4251

4252
4253
4254

4255
4256
4257
4258



4259
4260
4261
4262
4263
4264

4265
4266
4267

4268
4269
4270
4271
4272
4273
4274


4275
4276
4277

4278
4279
4280

4281
4282
4283
4284


4285
4286
4287
4288
4289
4290
4291





4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303


4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317


4318
4319
4320
4321
4322
4323
4324
4325





4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339



4340
4341

4342
4343
4344
4345
4346
4347
4348

4349
4350
4351

4352
4353
4354

4355
4356
4357
4358



4359
4360
4361
4362
4363

4364
4365
4366
4367
4368
4369
4370
4371







-
-
-
-
-
+
+
+
+
+
+






-
+






-
+
+

-
+


-
+


-
-
+
+












-
+
+






-
-
+
-



-
+





-
-
+
+

-
+
+

-
+



-
-
-
-
-
-
-
-

-
-
+
+


-
-
+
+


-
+














-
-
-
-
-
+
+
+
+
+
+







+
-
+
+
+
+

-
+

-
+










-
-
+
+

-
-
+
+








-
-
-
-
-
+
+
+
+
+
+







+
-
+
+
+
+

-
+

-
+










-
-
+
+

-
-
+
+







-
-
+
+








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

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

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


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

-
-
-
-
-
-
-
-
-
-
-

-
-
-
-
-


-
-
-
-
-
-
-
-
-
-
-

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

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

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


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




-
-
+
+

-
+
+

-
+



-
-
+
+



-
-
+
+

-
+
+

-
+



-
-
+
+

-
+
+






-
-
-
-
-
+
+
+
+
+
+








-
+






-
+
+

-
+


-
+



-
-
-
+
+
+
+


-
+


-
+






-
-
+
+

-
+
+

-
+



-
-
+
+





-
-
-
-
-
+
+
+
+
+
+






-
-
+
+












-
-
+
+






-
-
-
-
-
+
+
+
+
+
+








-
-
-


-
+






-
+
+

-
+


-
+



-
-
-
+
+
+
+

-
+








#------------------------------------------------------------------------
# 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
    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the compiler understands -pipe" >&5
$as_echo_n "checking if the compiler understands -pipe... " >&6; }
if ${tcl_cv_cc_pipe+:} false; then :
  $as_echo_n "(cached) " >&6
else
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the compiler understands -pipe" >&5
printf %s "checking if the compiler understands -pipe... " >&6; }
if test ${tcl_cv_cc_pipe+y}
then :
  printf %s "(cached) " >&6
else $as_nop

	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_cc_pipe=yes
else
else $as_nop
  tcl_cv_cc_pipe=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
	CFLAGS=$hold_cflags
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_pipe" >&5
$as_echo "$tcl_cv_cc_pipe" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_pipe" >&5
printf "%s\n" "$tcl_cv_cc_pipe" >&6; }
    if test $tcl_cv_cc_pipe = yes; then
	CFLAGS="$CFLAGS -pipe"
    fi
fi

#------------------------------------------------------------------------
# Embedded configuration information, encoding to use for the values, TIP #59
#------------------------------------------------------------------------



# Check whether --with-encoding was given.
if test "${with_encoding+set}" = set; then :
if test ${with_encoding+y}
then :
  withval=$with_encoding; with_tcencoding=${withval}
fi


    if test x"${with_tcencoding}" != x ; then

cat >>confdefs.h <<_ACEOF
#define TCL_CFGVAL_ENCODING "${with_tcencoding}"
printf "%s\n" "#define TCL_CFGVAL_ENCODING \"${with_tcencoding}\"" >>confdefs.h
_ACEOF

    else

$as_echo "#define TCL_CFGVAL_ENCODING \"iso8859-1\"" >>confdefs.h
printf "%s\n" "#define TCL_CFGVAL_ENCODING \"utf-8\"" >>confdefs.h

    fi



    { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to build libraries" >&5
$as_echo_n "checking how to build libraries... " >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to build libraries" >&5
printf %s "checking how to build libraries... " >&6; }
    # Check whether --enable-shared was given.
if test "${enable_shared+set}" = set; then :
if test ${enable_shared+y}
then :
  enableval=$enable_shared; tcl_ok=$enableval
else
else $as_nop
  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; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: shared" >&5
printf "%s\n" "shared" >&6; }
	SHARED_BUILD=1
    else
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
$as_echo "static" >&6; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: static" >&5
printf "%s\n" "static" >&6; }
	SHARED_BUILD=0

$as_echo "#define STATIC_BUILD 1" >>confdefs.h
printf "%s\n" "#define STATIC_BUILD 1" >>confdefs.h

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

if test -n "$ac_tool_prefix"; then
  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
set dummy ${ac_tool_prefix}ranlib; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_RANLIB+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_RANLIB+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
RANLIB=$ac_cv_prog_RANLIB
if test -n "$RANLIB"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
$as_echo "$RANLIB" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
printf "%s\n" "$RANLIB" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi


fi
if test -z "$ac_cv_prog_RANLIB"; then
  ac_ct_RANLIB=$RANLIB
  # Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_ac_ct_RANLIB+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_RANLIB="ranlib"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
if test -n "$ac_ct_RANLIB"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
$as_echo "$ac_ct_RANLIB" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
printf "%s\n" "$ac_ct_RANLIB" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "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;}
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    RANLIB=$ac_ct_RANLIB
  fi
else
  RANLIB="$ac_cv_prog_RANLIB"
fi

ac_ext=c
ac_header= ac_cache=
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
$as_echo_n "checking how to run the C preprocessor... " >&6; }
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
  CPP=
fi
if test -z "$CPP"; then
  if ${ac_cv_prog_CPP+:} false; then :
  $as_echo_n "(cached) " >&6
else
      # Double quotes because CPP needs to be expanded
    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
    do
      ac_preproc_ok=false
for ac_c_preproc_warn_flag in '' yes
for ac_item in $ac_header_c_list
do
  # Use a header file that comes with gcc, so configuring glibc
  # with a fresh cross-compiler works.
  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
  # <limits.h> exists even on freestanding compilers.
  # On the NeXT, cc -E runs the code through the compiler's parser,
  # not just through cpp. "Syntax error" is here to catch this case.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
  if test $ac_cache; then
		     Syntax error
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :

    ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default"
    if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then
else
  # Broken: fails on valid input.
continue
fi
      printf "%s\n" "#define $ac_item 1" >> confdefs.h
    fi
rm -f conftest.err conftest.i conftest.$ac_ext

  # OK, works on sane cases.  Now check whether nonexistent headers
  # can be detected and how.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <ac_nonexistent.h>
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :
  # Broken: success on invalid input.
continue
else
  # Passes both tests.
ac_preproc_ok=:
break
fi
rm -f conftest.err conftest.i conftest.$ac_ext

    ac_header= ac_cache=
done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
rm -f conftest.i conftest.err conftest.$ac_ext
if $ac_preproc_ok; then :
  break
fi

  elif test $ac_header; then
    done
    ac_cv_prog_CPP=$CPP

    ac_cache=$ac_item
fi
  CPP=$ac_cv_prog_CPP
else
  ac_cv_prog_CPP=$CPP
fi
  else
    ac_header=$ac_item
  fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
$as_echo "$CPP" >&6; }
ac_preproc_ok=false
for ac_c_preproc_warn_flag in '' yes
do
  # Use a header file that comes with gcc, so configuring glibc
  # with a fresh cross-compiler works.
  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
  # <limits.h> exists even on freestanding compilers.
  # On the NeXT, cc -E runs the code through the compiler's parser,
  # not just through cpp. "Syntax error" is here to catch this case.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
		     Syntax error
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :

else
  # Broken: fails on valid input.
continue
fi
rm -f conftest.err conftest.i conftest.$ac_ext

  # OK, works on sane cases.  Now check whether nonexistent headers
  # can be detected and how.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <ac_nonexistent.h>
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :
  # Broken: success on invalid input.
continue
else
  # Passes both tests.
ac_preproc_ok=:
break
fi
rm -f conftest.err conftest.i conftest.$ac_ext

done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
rm -f conftest.i conftest.err conftest.$ac_ext
if $ac_preproc_ok; then :

else
  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
See \`config.log' for more details" "$LINENO" 5; }
fi

ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
if ${ac_cv_path_GREP+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if test -z "$GREP"; then
  ac_path_GREP_found=false
  # Loop through the user's path and test for each of PROGNAME-LIST
  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_prog in grep ggrep; do
    for ac_exec_ext in '' $ac_executable_extensions; do
      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
      as_fn_executable_p "$ac_path_GREP" || continue
# Check for GNU ac_path_GREP and select it if it is found.
  # Check for GNU $ac_path_GREP
case `"$ac_path_GREP" --version 2>&1` in
*GNU*)
  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
*)
  ac_count=0
  $as_echo_n 0123456789 >"conftest.in"
  while :
  do
    cat "conftest.in" "conftest.in" >"conftest.tmp"
    mv "conftest.tmp" "conftest.in"
    cp "conftest.in" "conftest.nl"
    $as_echo 'GREP' >> "conftest.nl"
    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
    as_fn_arith $ac_count + 1 && ac_count=$as_val
    if test $ac_count -gt ${ac_path_GREP_max-0}; then
      # Best one so far, save it but keep looking for a better one
      ac_cv_path_GREP="$ac_path_GREP"
      ac_path_GREP_max=$ac_count
    fi
    # 10*(2^10) chars as input seems more than enough
    test $ac_count -gt 10 && break
  done
  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
esac

      $ac_path_GREP_found && break 3
    done
  done
  done
IFS=$as_save_IFS
  if test -z "$ac_cv_path_GREP"; then
    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
  fi
else
  ac_cv_path_GREP=$GREP
fi

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
$as_echo "$ac_cv_path_GREP" >&6; }
 GREP="$ac_cv_path_GREP"


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
$as_echo_n "checking for egrep... " >&6; }
if ${ac_cv_path_EGREP+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
   then ac_cv_path_EGREP="$GREP -E"
   else
     if test -z "$EGREP"; then
  ac_path_EGREP_found=false
  # Loop through the user's path and test for each of PROGNAME-LIST
  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_prog in egrep; do
    for ac_exec_ext in '' $ac_executable_extensions; do
      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
      as_fn_executable_p "$ac_path_EGREP" || continue
# Check for GNU ac_path_EGREP and select it if it is found.
  # Check for GNU $ac_path_EGREP
case `"$ac_path_EGREP" --version 2>&1` in
*GNU*)
  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
*)
  ac_count=0
  $as_echo_n 0123456789 >"conftest.in"
  while :
  do
    cat "conftest.in" "conftest.in" >"conftest.tmp"
    mv "conftest.tmp" "conftest.in"
    cp "conftest.in" "conftest.nl"
    $as_echo 'EGREP' >> "conftest.nl"
    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
    as_fn_arith $ac_count + 1 && ac_count=$as_val
    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
      # Best one so far, save it but keep looking for a better one
      ac_cv_path_EGREP="$ac_path_EGREP"
      ac_path_EGREP_max=$ac_count
    fi
    # 10*(2^10) chars as input seems more than enough
    test $ac_count -gt 10 && break
  done
  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
esac

      $ac_path_EGREP_found && break 3
    done
  done
  done
IFS=$as_save_IFS
  if test -z "$ac_cv_path_EGREP"; then
    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
  fi
else
  ac_cv_path_EGREP=$EGREP
fi

   fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
$as_echo "$ac_cv_path_EGREP" >&6; }
 EGREP="$ac_cv_path_EGREP"


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
$as_echo_n "checking for ANSI C header files... " >&6; }
if ${ac_cv_header_stdc+:} false; then :
  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <float.h>

int
main ()
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
  ac_cv_header_stdc=yes
else
  ac_cv_header_stdc=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

if test $ac_cv_header_stdc = yes; then
  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <string.h>

_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  $EGREP "memchr" >/dev/null 2>&1; then :

else
  ac_cv_header_stdc=no
fi
rm -f conftest*

fi

if test $ac_cv_header_stdc = yes; then
if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes
  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <stdlib.h>

then :
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  $EGREP "free" >/dev/null 2>&1; then :

else
  ac_cv_header_stdc=no
fi
rm -f conftest*

fi

if test $ac_cv_header_stdc = yes; then
  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
  if test "$cross_compiling" = yes; then :
  :
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <ctype.h>
#include <stdlib.h>
#if ((' ' & 0x0FF) == 0x020)
# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
#else
# define ISLOWER(c) \
		   (('a' <= (c) && (c) <= 'i') \
		     || ('j' <= (c) && (c) <= 'r') \
		     || ('s' <= (c) && (c) <= 'z'))
# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
#endif

#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
int
main ()
{
  int i;
  for (i = 0; i < 256; i++)
    if (XOR (islower (i), ISLOWER (i))
	|| toupper (i) != TOUPPER (i))
      return 2;
  return 0;
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :

else
  ac_cv_header_stdc=no
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
  conftest.$ac_objext conftest.beam conftest.$ac_ext
fi

fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
$as_echo "$ac_cv_header_stdc" >&6; }
if test $ac_cv_header_stdc = yes; then

$as_echo "#define STDC_HEADERS 1" >>confdefs.h
printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h

fi

# 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.a: 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; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if 64bit support is requested" >&5
printf %s "checking if 64bit support is requested... " >&6; }
    # Check whether --enable-64bit was given.
if test "${enable_64bit+set}" = set; then :
if test ${enable_64bit+y}
then :
  enableval=$enable_64bit; do64bit=$enableval
else
else $as_nop
  do64bit=no
fi

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bit" >&5
$as_echo "$do64bit" >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $do64bit" >&5
printf "%s\n" "$do64bit" >&6; }

    # Step 0.b: Enable Solaris 64 bit VIS support?

    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if 64bit Sparc VIS support is requested" >&5
$as_echo_n "checking if 64bit Sparc VIS support is requested... " >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if 64bit Sparc VIS support is requested" >&5
printf %s "checking if 64bit Sparc VIS support is requested... " >&6; }
    # Check whether --enable-64bit-vis was given.
if test "${enable_64bit_vis+set}" = set; then :
if test ${enable_64bit_vis+y}
then :
  enableval=$enable_64bit_vis; do64bitVIS=$enableval
else
else $as_nop
  do64bitVIS=no
fi

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bitVIS" >&5
$as_echo "$do64bitVIS" >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $do64bitVIS" >&5
printf "%s\n" "$do64bitVIS" >&6; }
    # Force 64bit on with VIS
    if test "$do64bitVIS" = "yes"; then :
    if test "$do64bitVIS" = "yes"
then :
  do64bit=yes
fi

    # Step 0.c: Check if visibility support is available. Do this here so
    # that platform specific alternatives can be used below if this fails.

    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports visibility \"hidden\"" >&5
$as_echo_n "checking if compiler supports visibility \"hidden\"... " >&6; }
if ${tcl_cv_cc_visibility_hidden+:} false; then :
  $as_echo_n "(cached) " >&6
else
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiler supports visibility \"hidden\"" >&5
printf %s "checking if compiler supports visibility \"hidden\"... " >&6; }
if test ${tcl_cv_cc_visibility_hidden+y}
then :
  printf %s "(cached) " >&6
else $as_nop

	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

	    extern __attribute__((__visibility__("hidden"))) void f(void);
	    void f(void) {}
int
main ()
main (void)
{
f();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_cc_visibility_hidden=yes
else
else $as_nop
  tcl_cv_cc_visibility_hidden=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
	CFLAGS=$hold_cflags
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_visibility_hidden" >&5
$as_echo "$tcl_cv_cc_visibility_hidden" >&6; }
    if test $tcl_cv_cc_visibility_hidden = yes; then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_visibility_hidden" >&5
printf "%s\n" "$tcl_cv_cc_visibility_hidden" >&6; }
    if test $tcl_cv_cc_visibility_hidden = yes
then :


$as_echo "#define MODULE_SCOPE extern __attribute__((__visibility__(\"hidden\")))" >>confdefs.h
printf "%s\n" "#define MODULE_SCOPE extern __attribute__((__visibility__(\"hidden\")))" >>confdefs.h


$as_echo "#define HAVE_HIDDEN 1" >>confdefs.h
printf "%s\n" "#define HAVE_HIDDEN 1" >>confdefs.h


fi

    # Step 0.d: Disable -rpath support?

    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if rpath support is requested" >&5
$as_echo_n "checking if rpath support is requested... " >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if rpath support is requested" >&5
printf %s "checking if rpath support is requested... " >&6; }
    # Check whether --enable-rpath was given.
if test "${enable_rpath+set}" = set; then :
if test ${enable_rpath+y}
then :
  enableval=$enable_rpath; doRpath=$enableval
else
else $as_nop
  doRpath=yes
fi

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $doRpath" >&5
$as_echo "$doRpath" >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $doRpath" >&5
printf "%s\n" "$doRpath" >&6; }

    # Step 1: set the variable "system" to hold the name and version number
    # for the system.


    { $as_echo "$as_me:${as_lineno-$LINENO}: checking system version" >&5
$as_echo_n "checking system version... " >&6; }
if ${tcl_cv_sys_version+:} false; then :
  $as_echo_n "(cached) " >&6
else
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking system version" >&5
printf %s "checking system version... " >&6; }
if test ${tcl_cv_sys_version+y}
then :
  printf %s "(cached) " >&6
else $as_nop

	if test "${TEA_PLATFORM}" = "windows" ; then
	    tcl_cv_sys_version=windows
	else
	    tcl_cv_sys_version=`uname -s`-`uname -r`
	    if test "$?" -ne 0 ; then
		{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: can't find uname command" >&5
$as_echo "$as_me: WARNING: can't find uname command" >&2;}
		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: can't find uname command" >&5
printf "%s\n" "$as_me: WARNING: can't find uname command" >&2;}
		tcl_cv_sys_version=unknown
	    else
		if test "`uname -s`" = "AIX" ; then
		    tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
		fi
		if test "`uname -s`" = "NetBSD" -a -f /etc/debian_version ; then
		    tcl_cv_sys_version=NetBSD-Debian
		fi
	    fi
	fi

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_sys_version" >&5
$as_echo "$tcl_cv_sys_version" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_sys_version" >&5
printf "%s\n" "$tcl_cv_sys_version" >&6; }
    system=$tcl_cv_sys_version


    # Step 2: check for existence of -ldl library.  This is needed because
    # Linux can use either -ldl or -ldld for dynamic loading.

    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
$as_echo_n "checking for dlopen in -ldl... " >&6; }
if ${ac_cv_lib_dl_dlopen+:} false; then :
  $as_echo_n "(cached) " >&6
else
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
printf %s "checking for dlopen in -ldl... " >&6; }
if test ${ac_cv_lib_dl_dlopen+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  ac_check_lib_save_LIBS=$LIBS
LIBS="-ldl  $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

/* Override any GCC internal prototype to avoid an error.
   Use char because int might match the return type of a GCC
   builtin and then its argument prototype would still apply.  */
#ifdef __cplusplus
extern "C"
#endif
char dlopen ();
int
main ()
main (void)
{
return dlopen ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_lib_dl_dlopen=yes
else
else $as_nop
  ac_cv_lib_dl_dlopen=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; }
if test "x$ac_cv_lib_dl_dlopen" = xyes
then :
  have_dl=yes
else
else $as_nop
  have_dl=no
fi


    # Require ranlib early so we can override it in special cases below.


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







-
+
+


-
+




-
+




-
+








-
-
-
-
-
+
+
+
+
+
+







+
-
+
+
+
+

-
+

-
+










-
-
+
+

-
-
+
+








-
-
-
-
-
+
+
+
+
+
+







+
-
+
+
+
+

-
+

-
+










-
-
+
+

-
-
+
+







-
-
+
+













-
+
+




-
+
+











-
-
+
+














-
+
+

-
+
+

-
-
+
+

-
+












-
+
+





-
+
+



-
+






-
+

-
+
+



-
+







    # is disabled by the user. [Bug 1016796]
    LDFLAGS_ARCH=""
    UNSHARED_LIB_SUFFIX=""
    TCL_TRIM_DOTS='`echo ${VERSION} | tr -d .`'
    ECHO_VERSION='`echo ${VERSION}`'
    TCL_LIB_VERSIONS_OK=ok
    CFLAGS_DEBUG=-g
    if test "$GCC" = yes; then :
    if test "$GCC" = yes
then :

	CFLAGS_OPTIMIZE=-O2
	CFLAGS_WARNING="-Wall -Wextra -Wwrite-strings -Wpointer-arith"
	CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith -finput-charset=UTF-8"
	case "${CC}" in
	    *++|*++-*)
		;;
	    *)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -Wdeclaration-after-statement"
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -fextended-identifiers"
		;;
	esac


else
else $as_nop

	CFLAGS_OPTIMIZE=-O
	CFLAGS_WARNING=""

fi
    if test -n "$ac_tool_prefix"; then
  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
set dummy ${ac_tool_prefix}ar; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_AR+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_AR+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_AR="${ac_tool_prefix}ar"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
AR=$ac_cv_prog_AR
if test -n "$AR"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
$as_echo "$AR" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
printf "%s\n" "$AR" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi


fi
if test -z "$ac_cv_prog_AR"; then
  ac_ct_AR=$AR
  # Extract the first word of "ar", so it can be a program name with args.
set dummy ar; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_AR+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_ac_ct_AR+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_AR="ar"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
ac_ct_AR=$ac_cv_prog_ac_ct_AR
if test -n "$ac_ct_AR"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
$as_echo "$ac_ct_AR" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
printf "%s\n" "$ac_ct_AR" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "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;}
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    AR=$ac_ct_AR
  fi
else
  AR="$ac_cv_prog_AR"
fi

    STLIB_LD='${AR} cr'
    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
    PLAT_OBJS=""
    PLAT_SRCS=""
    LDAIX_SRC=""
    if test "x${SHLIB_VERSION}" = x; then :
    if test "x${SHLIB_VERSION}" = x
then :
  SHLIB_VERSION="1.0"
fi
    case $system in
	AIX-*)
	    if test "$GCC" != "yes"; then :
	    if test "$GCC" != "yes"
then :

		# AIX requires the _r compiler when gcc isn't being used
		case "${CC}" in
		    *_r|*_r\ *)
			# ok ...
			;;
		    *)
			# Make sure only first arg gets _r
		    	CC=`echo "$CC" | sed -e 's/^\([^ ]*\)/\1_r/'`
			;;
		esac
		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Using $CC for compiling with threads" >&5
$as_echo "Using $CC for compiling with threads" >&6; }
		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using $CC for compiling with threads" >&5
printf "%s\n" "Using $CC for compiling with threads" >&6; }

fi
	    LIBS="$LIBS -lc"
	    SHLIB_CFLAGS=""
	    SHLIB_SUFFIX=".so"

	    DL_OBJS="tclLoadDl.o"
	    LD_LIBRARY_PATH_VAR="LIBPATH"

	    # ldAix No longer needed with use of -bexpall/-brtl
	    # but some extensions may still reference it
	    LDAIX_SRC='$(UNIX_DIR)/ldAix'

	    # Check to enable 64-bit flags for compiler/linker
	    if test "$do64bit" = yes; then :
	    if test "$do64bit" = yes
then :

		if test "$GCC" = yes; then :
		if test "$GCC" = yes
then :

		    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5
$as_echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
		    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5
printf "%s\n" "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}

else
else $as_nop

		    do64bit_ok=yes
		    CFLAGS="$CFLAGS -q64"
		    LDFLAGS_ARCH="-q64"
		    RANLIB="${RANLIB} -X64"
		    AR="${AR} -X64"
		    SHLIB_LD_FLAGS="-b64"

fi

fi

	    if test "`uname -m`" = ia64; then :
	    if test "`uname -m`" = ia64
then :

		# AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
		SHLIB_LD="/usr/ccs/bin/ld -G -z text"
		# AIX-5 has dl* in libc.so
		DL_LIBS=""
		if test "$GCC" = yes; then :
		if test "$GCC" = yes
then :

		    CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'

else
else $as_nop

		    CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'

fi
		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'

else
else $as_nop

		if test "$GCC" = yes; then :
		if test "$GCC" = yes
then :

		    SHLIB_LD='${CC} -shared -Wl,-bexpall'

else
else $as_nop

		    SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry"
		    LDFLAGS="$LDFLAGS -brtl"

fi
		SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}"
		DL_LIBS="-ldl"
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
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







-
-
-
-
-
+
+
+
+
+
+








-
-
-


-
+






-
+
+

-
+


-
+



-
-
-
+
+
+
+







	    DL_LIBS="-ldl"

	    #-----------------------------------------------------------
	    # Check for inet_ntoa in -lbind, for BeOS (which also needs
	    # -lsocket, even if the network functions are in -lnet which
	    # is always linked to, for compatibility.
	    #-----------------------------------------------------------
	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa in -lbind" >&5
$as_echo_n "checking for inet_ntoa in -lbind... " >&6; }
if ${ac_cv_lib_bind_inet_ntoa+:} false; then :
  $as_echo_n "(cached) " >&6
else
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa in -lbind" >&5
printf %s "checking for inet_ntoa in -lbind... " >&6; }
if test ${ac_cv_lib_bind_inet_ntoa+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  ac_check_lib_save_LIBS=$LIBS
LIBS="-lbind  $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

/* Override any GCC internal prototype to avoid an error.
   Use char because int might match the return type of a GCC
   builtin and then its argument prototype would still apply.  */
#ifdef __cplusplus
extern "C"
#endif
char inet_ntoa ();
int
main ()
main (void)
{
return inet_ntoa ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_lib_bind_inet_ntoa=yes
else
else $as_nop
  ac_cv_lib_bind_inet_ntoa=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bind_inet_ntoa" >&5
$as_echo "$ac_cv_lib_bind_inet_ntoa" >&6; }
if test "x$ac_cv_lib_bind_inet_ntoa" = xyes; then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bind_inet_ntoa" >&5
printf "%s\n" "$ac_cv_lib_bind_inet_ntoa" >&6; }
if test "x$ac_cv_lib_bind_inet_ntoa" = xyes
then :
  LIBS="$LIBS -lbind -lsocket"
fi

	    ;;
	BSD/OS-2.1*|BSD/OS-3*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="shlicc -r"
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
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







-
+












-
-
-
-
-
+
+
+
+
+
+








-
+






-
+
+

-
+


-
+


-
-
+
+







	    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,\[email protected]"
	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Cygwin version of gcc" >&5
$as_echo_n "checking for Cygwin version of gcc... " >&6; }
if ${ac_cv_cygwin+:} false; then :
  $as_echo_n "(cached) " >&6
else
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Cygwin version of gcc" >&5
printf %s "checking for Cygwin version of gcc... " >&6; }
if test ${ac_cv_cygwin+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

		#ifdef __CYGWIN__
		    #error cygwin
		#endif

int
main ()
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_cygwin=no
else
else $as_nop
  ac_cv_cygwin=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cygwin" >&5
$as_echo "$ac_cv_cygwin" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cygwin" >&5
printf "%s\n" "$ac_cv_cygwin" >&6; }
	    if test "$ac_cv_cygwin" = "no"; then
		as_fn_error $? "${CC} is not a cygwin compiler." "$LINENO" 5
	    fi
	    do64bit_ok=yes
	    if test "x${SHARED_BUILD}" = "x1"; then
		echo "running cd ../win; ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args"
		# The eval makes quoting arguments work.
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
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







-
-
-
-
-
+
+
+
+
+
+








-
-
-


-
+






-
+
+

-
+


-
+



-
-
-
+
+
+
+







-
+


-
+



-
+
+



-
+




-
-
-
-
-
+
+
+
+
+
+








-
-
-


-
+






-
+
+

-
+


-
+



-
-
-
+
+
+
+

-
+



-
+
+











-
+
+




-
+









-
+
+

-
+
+






-
+
+






-
-
+
+



-
+










-
-
-
-
-
+
+
+
+
+
+








-
-
-


-
+






-
+
+

-
+


-
+



-
-
-
+
+
+
+

-
+



-
+
+







	Haiku*)
	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_SUFFIX=".so"
	    SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared'
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-lroot"
	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa in -lnetwork" >&5
$as_echo_n "checking for inet_ntoa in -lnetwork... " >&6; }
if ${ac_cv_lib_network_inet_ntoa+:} false; then :
  $as_echo_n "(cached) " >&6
else
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa in -lnetwork" >&5
printf %s "checking for inet_ntoa in -lnetwork... " >&6; }
if test ${ac_cv_lib_network_inet_ntoa+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  ac_check_lib_save_LIBS=$LIBS
LIBS="-lnetwork  $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

/* Override any GCC internal prototype to avoid an error.
   Use char because int might match the return type of a GCC
   builtin and then its argument prototype would still apply.  */
#ifdef __cplusplus
extern "C"
#endif
char inet_ntoa ();
int
main ()
main (void)
{
return inet_ntoa ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_lib_network_inet_ntoa=yes
else
else $as_nop
  ac_cv_lib_network_inet_ntoa=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_network_inet_ntoa" >&5
$as_echo "$ac_cv_lib_network_inet_ntoa" >&6; }
if test "x$ac_cv_lib_network_inet_ntoa" = xyes; then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_network_inet_ntoa" >&5
printf "%s\n" "$ac_cv_lib_network_inet_ntoa" >&6; }
if test "x$ac_cv_lib_network_inet_ntoa" = xyes
then :
  LIBS="$LIBS -lnetwork"
fi

	    ;;
	HP-UX-*.11.*)
	    # Use updated header definitions where possible

$as_echo "#define _XOPEN_SOURCE_EXTENDED 1" >>confdefs.h
printf "%s\n" "#define _XOPEN_SOURCE_EXTENDED 1" >>confdefs.h


$as_echo "#define _XOPEN_SOURCE 1" >>confdefs.h
printf "%s\n" "#define _XOPEN_SOURCE 1" >>confdefs.h

	    LIBS="$LIBS -lxnet"               # Use the XOPEN network library

	    if test "`uname -m`" = ia64; then :
	    if test "`uname -m`" = ia64
then :

		SHLIB_SUFFIX=".so"

else
else $as_nop

		SHLIB_SUFFIX=".sl"

fi
	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
$as_echo_n "checking for shl_load in -ldld... " >&6; }
if ${ac_cv_lib_dld_shl_load+:} false; then :
  $as_echo_n "(cached) " >&6
else
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
printf %s "checking for shl_load in -ldld... " >&6; }
if test ${ac_cv_lib_dld_shl_load+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  ac_check_lib_save_LIBS=$LIBS
LIBS="-ldld  $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

/* Override any GCC internal prototype to avoid an error.
   Use char because int might match the return type of a GCC
   builtin and then its argument prototype would still apply.  */
#ifdef __cplusplus
extern "C"
#endif
char shl_load ();
int
main ()
main (void)
{
return shl_load ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_lib_dld_shl_load=yes
else
else $as_nop
  ac_cv_lib_dld_shl_load=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
printf "%s\n" "$ac_cv_lib_dld_shl_load" >&6; }
if test "x$ac_cv_lib_dld_shl_load" = xyes
then :
  tcl_ok=yes
else
else $as_nop
  tcl_ok=no
fi

	    if test "$tcl_ok" = yes; then :
	    if test "$tcl_ok" = yes
then :

		SHLIB_CFLAGS="+z"
		SHLIB_LD="ld -b"
		DL_OBJS="tclLoadShl.o"
		DL_LIBS="-ldld"
		LDFLAGS="$LDFLAGS -Wl,-E"
		CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
		LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
		LD_LIBRARY_PATH_VAR="SHLIB_PATH"

fi
	    if test "$GCC" = yes; then :
	    if test "$GCC" = yes
then :

		SHLIB_LD='${CC} -shared'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}

else
else $as_nop

		CFLAGS="$CFLAGS -z"

fi

	    # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
	    #CFLAGS="$CFLAGS +DAportable"

	    # Check to enable 64-bit flags for compiler/linker
	    if test "$do64bit" = "yes"; then :
	    if test "$do64bit" = "yes"
then :

		if test "$GCC" = yes; then :
		if test "$GCC" = yes
then :

		    case `${CC} -dumpmachine` in
			hppa64*)
			    # 64-bit gcc in use.  Fix flags for GNU ld.
			    do64bit_ok=yes
			    SHLIB_LD='${CC} -shared'
			    if test $doRpath = yes; then :
			    if test $doRpath = yes
then :

				CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
fi
			    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
			    ;;
			*)
			    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5
$as_echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
			    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5
printf "%s\n" "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
			    ;;
		    esac

else
else $as_nop

		    do64bit_ok=yes
		    CFLAGS="$CFLAGS +DD64"
		    LDFLAGS_ARCH="+DD64"

fi

fi ;;
	HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*)
	    SHLIB_SUFFIX=".sl"
	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
$as_echo_n "checking for shl_load in -ldld... " >&6; }
if ${ac_cv_lib_dld_shl_load+:} false; then :
  $as_echo_n "(cached) " >&6
else
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
printf %s "checking for shl_load in -ldld... " >&6; }
if test ${ac_cv_lib_dld_shl_load+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  ac_check_lib_save_LIBS=$LIBS
LIBS="-ldld  $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

/* Override any GCC internal prototype to avoid an error.
   Use char because int might match the return type of a GCC
   builtin and then its argument prototype would still apply.  */
#ifdef __cplusplus
extern "C"
#endif
char shl_load ();
int
main ()
main (void)
{
return shl_load ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_lib_dld_shl_load=yes
else
else $as_nop
  ac_cv_lib_dld_shl_load=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
printf "%s\n" "$ac_cv_lib_dld_shl_load" >&6; }
if test "x$ac_cv_lib_dld_shl_load" = xyes
then :
  tcl_ok=yes
else
else $as_nop
  tcl_ok=no
fi

	    if test "$tcl_ok" = yes; then :
	    if test "$tcl_ok" = yes
then :

		SHLIB_CFLAGS="+z"
		SHLIB_LD="ld -b"
		SHLIB_LD_LIBS=""
		DL_OBJS="tclLoadShl.o"
		DL_LIBS="-ldld"
		LDFLAGS="$LDFLAGS -Wl,-E"
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
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







-
+
+

















-
+
+




-
+
+




-
+







	    DL_LIBS=""
	    case " $LIBOBJS " in
  *" mkstemp.$ac_objext "* ) ;;
  *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext"
 ;;
esac

	    if test $doRpath = yes; then :
	    if test $doRpath = yes
then :

		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
fi
	    ;;
	IRIX-6.*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="ld -n32 -shared -rdata_shared"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    case " $LIBOBJS " in
  *" mkstemp.$ac_objext "* ) ;;
  *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext"
 ;;
esac

	    if test $doRpath = yes; then :
	    if test $doRpath = yes
then :

		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
fi
	    if test "$GCC" = yes; then :
	    if test "$GCC" = yes
then :

		CFLAGS="$CFLAGS -mabi=n32"
		LDFLAGS="$LDFLAGS -mabi=n32"

else
else $as_nop

		case $system in
		    IRIX-6.3)
			# Use to build 6.2 compatible binaries on 6.3.
			CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
			;;
		    *)
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
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







-
+
+







-
+
+

-
+
+

-
-
+
+

-
+







	    DL_LIBS=""
	    case " $LIBOBJS " in
  *" mkstemp.$ac_objext "* ) ;;
  *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext"
 ;;
esac

	    if test $doRpath = yes; then :
	    if test $doRpath = yes
then :

		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
fi

	    # Check to enable 64-bit flags for compiler/linker

	    if test "$do64bit" = yes; then :
	    if test "$do64bit" = yes
then :

	        if test "$GCC" = yes; then :
	        if test "$GCC" = yes
then :

	            { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported by gcc" >&5
$as_echo "$as_me: WARNING: 64bit mode not supported by gcc" >&2;}
	            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported by gcc" >&5
printf "%s\n" "$as_me: WARNING: 64bit mode not supported by gcc" >&2;}

else
else $as_nop

	            do64bit_ok=yes
	            SHLIB_LD="ld -64 -shared -rdata_shared"
	            CFLAGS="$CFLAGS -64"
	            LDFLAGS_ARCH="-64"

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







-
+
+




-
+
+


-
+
+

-
-
-
-
-
+
+
+
+
+
+







-
+






-
+
+

-
+


-
+



-
-
-
+
+
+
+














-
+
+











-
+
+



















-
+
+







	    # 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"
	    if test $doRpath = yes; then :
	    if test $doRpath = yes
then :

		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
fi
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    if test "`uname -m`" = "alpha"; then :
	    if test "`uname -m`" = "alpha"
then :
  CFLAGS="$CFLAGS -mieee"
fi
	    if test $do64bit = yes; then :
	    if test $do64bit = yes
then :

		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -m64 flag" >&5
$as_echo_n "checking if compiler accepts -m64 flag... " >&6; }
if ${tcl_cv_cc_m64+:} false; then :
  $as_echo_n "(cached) " >&6
else
		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -m64 flag" >&5
printf %s "checking if compiler accepts -m64 flag... " >&6; }
if test ${tcl_cv_cc_m64+y}
then :
  printf %s "(cached) " >&6
else $as_nop

		    hold_cflags=$CFLAGS
		    CFLAGS="$CFLAGS -m64"
		    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_cc_m64=yes
else
else $as_nop
  tcl_cv_cc_m64=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
		    CFLAGS=$hold_cflags
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_m64" >&5
$as_echo "$tcl_cv_cc_m64" >&6; }
		if test $tcl_cv_cc_m64 = yes; then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_m64" >&5
printf "%s\n" "$tcl_cv_cc_m64" >&6; }
		if test $tcl_cv_cc_m64 = yes
then :

		    CFLAGS="$CFLAGS -m64"
		    do64bit_ok=yes

fi

fi

	    # The combo of gcc + glibc has a bug related to inlining of
	    # functions like strtol()/strtoul(). The -fno-builtin flag should address
	    # this problem but it does not work. The -fno-inline flag is kind
	    # of overkill but it works. Disable inlining only when one of the
	    # files in compat/*.c is being linked in.

	    if test x"${USE_COMPAT}" != x; then :
	    if test x"${USE_COMPAT}" != x
then :
  CFLAGS="$CFLAGS -fno-inline"
fi
	    ;;
	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"
	    if test $doRpath = yes; then :
	    if test $doRpath = yes
then :

		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
		LD_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
fi
	    ;;
	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=""
	    if test $doRpath = yes; then :
	    if test $doRpath = yes
then :

		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
fi
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
	    LDFLAGS="-Wl,-export-dynamic"
	    CFLAGS_OPTIMIZE="-O2"
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
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







-
+
+
















-
+
+







	    # 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"
	    if test $doRpath = yes; then :
	    if test $doRpath = yes
then :

		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
fi
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    # The -pthread needs to go in the CFLAGS, not LIBS
	    LIBS=`echo $LIBS | sed s/-pthread//`
	    CFLAGS="$CFLAGS -pthread"
	    LDFLAGS="$LDFLAGS -pthread"
	    ;;
	DragonFly-*|FreeBSD-*)
	    # This configuration from FreeBSD Ports.
	    SHLIB_LD="${CC} -shared"
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\$@"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    if test $doRpath = yes; then :
	    if test $doRpath = yes
then :

		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
		LD_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
fi
	    # The -pthread needs to go in the LDFLAGS, not LIBS
	    LIBS=`echo $LIBS | sed s/-pthread//`
	    CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
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
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







-
+
+



-
-
-
-
-
+
+
+
+
+
+







-
+






-
+
+

-
+


-
+



-
-
-
+
+
+
+






-
-
-
-
-
+
+
+
+
+
+







-
+






-
+
+

-
+


-
+



-
-
-
+
+
+
+






-
-
+
+


-
+



-
+
+






-
-
-
-
-
+
+
+
+
+
+







-
+






-
+
+

-
+


-
+



-
-
-
+
+
+
+








-
-
-
-
-
+
+
+
+
+
+







-
+






-
+
+

-
+


-
+



-
-
-
+
+
+
+




-
+
+


-
+








-
+



-
-
+
+

-
+
+

-
+



-
-
-
+
+
+
+

-
-
-
-
-
+
+
+
+
+
+


-
+
+














-
+






-
+
+

-
+


-
+

-
+
+







-
-
-
+
+
+
+



-
+


-
+


-
+
+

-
-
-
-
-
+
+
+
+
+
+








-
+






-
+
+

-
+


-
+





-
-
-
+
+
+
+


-
+













-
+





-
+
+



-
+







-
+
+




-
+
+

-
+







-
+
+



-
+







	    # -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}'`"
	    if test $do64bit = yes; then :
	    if test $do64bit = yes
then :

		case `arch` in
		    ppc)
			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -arch ppc64 flag" >&5
$as_echo_n "checking if compiler accepts -arch ppc64 flag... " >&6; }
if ${tcl_cv_cc_arch_ppc64+:} false; then :
  $as_echo_n "(cached) " >&6
else
			{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -arch ppc64 flag" >&5
printf %s "checking if compiler accepts -arch ppc64 flag... " >&6; }
if test ${tcl_cv_cc_arch_ppc64+y}
then :
  printf %s "(cached) " >&6
else $as_nop

			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
			    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_cc_arch_ppc64=yes
else
else $as_nop
  tcl_cv_cc_arch_ppc64=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
			    CFLAGS=$hold_cflags
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_arch_ppc64" >&5
$as_echo "$tcl_cv_cc_arch_ppc64" >&6; }
			if test $tcl_cv_cc_arch_ppc64 = yes; then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_arch_ppc64" >&5
printf "%s\n" "$tcl_cv_cc_arch_ppc64" >&6; }
			if test $tcl_cv_cc_arch_ppc64 = yes
then :

			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
			    do64bit_ok=yes

fi;;
		    i386)
			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -arch x86_64 flag" >&5
$as_echo_n "checking if compiler accepts -arch x86_64 flag... " >&6; }
if ${tcl_cv_cc_arch_x86_64+:} false; then :
  $as_echo_n "(cached) " >&6
else
			{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -arch x86_64 flag" >&5
printf %s "checking if compiler accepts -arch x86_64 flag... " >&6; }
if test ${tcl_cv_cc_arch_x86_64+y}
then :
  printf %s "(cached) " >&6
else $as_nop

			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch x86_64"
			    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_cc_arch_x86_64=yes
else
else $as_nop
  tcl_cv_cc_arch_x86_64=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
			    CFLAGS=$hold_cflags
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_arch_x86_64" >&5
$as_echo "$tcl_cv_cc_arch_x86_64" >&6; }
			if test $tcl_cv_cc_arch_x86_64 = yes; then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_arch_x86_64" >&5
printf "%s\n" "$tcl_cv_cc_arch_x86_64" >&6; }
			if test $tcl_cv_cc_arch_x86_64 = yes
then :

			    CFLAGS="$CFLAGS -arch x86_64"
			    do64bit_ok=yes

fi;;
		    *)
			{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&5
$as_echo "$as_me: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&2;};;
			{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&5
printf "%s\n" "$as_me: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&2;};;
		esac

else
else $as_nop

		# Check for combined 32-bit and 64-bit fat build
		if echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
		    && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '; then :
		    && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '
then :

		    fat_32_64=yes
fi

fi
	    SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS}'
	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ld accepts -single_module flag" >&5
$as_echo_n "checking if ld accepts -single_module flag... " >&6; }
if ${tcl_cv_ld_single_module+:} false; then :
  $as_echo_n "(cached) " >&6
else
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if ld accepts -single_module flag" >&5
printf %s "checking if ld accepts -single_module flag... " >&6; }
if test ${tcl_cv_ld_single_module+y}
then :
  printf %s "(cached) " >&6
else $as_nop

		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
main (void)
{
int i;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_ld_single_module=yes
else
else $as_nop
  tcl_cv_ld_single_module=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
		LDFLAGS=$hold_ldflags
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_single_module" >&5
$as_echo "$tcl_cv_ld_single_module" >&6; }
	    if test $tcl_cv_ld_single_module = yes; then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_single_module" >&5
printf "%s\n" "$tcl_cv_ld_single_module" >&6; }
	    if test $tcl_cv_ld_single_module = yes
then :

		SHLIB_LD="${SHLIB_LD} -Wl,-single_module"

fi
	    SHLIB_SUFFIX=".dylib"
	    DL_OBJS="tclLoadDyld.o"
	    DL_LIBS=""
	    LDFLAGS="$LDFLAGS -headerpad_max_install_names"
	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ld accepts -search_paths_first flag" >&5
$as_echo_n "checking if ld accepts -search_paths_first flag... " >&6; }
if ${tcl_cv_ld_search_paths_first+:} false; then :
  $as_echo_n "(cached) " >&6
else
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if ld accepts -search_paths_first flag" >&5
printf %s "checking if ld accepts -search_paths_first flag... " >&6; }
if test ${tcl_cv_ld_search_paths_first+y}
then :
  printf %s "(cached) " >&6
else $as_nop

		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
main (void)
{
int i;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_ld_search_paths_first=yes
else
else $as_nop
  tcl_cv_ld_search_paths_first=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
		LDFLAGS=$hold_ldflags
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_search_paths_first" >&5
$as_echo "$tcl_cv_ld_search_paths_first" >&6; }
	    if test $tcl_cv_ld_search_paths_first = yes; then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_search_paths_first" >&5
printf "%s\n" "$tcl_cv_ld_search_paths_first" >&6; }
	    if test $tcl_cv_ld_search_paths_first = yes
then :

		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"

fi
	    if test "$tcl_cv_cc_visibility_hidden" != yes; then :
	    if test "$tcl_cv_cc_visibility_hidden" != yes
then :


$as_echo "#define MODULE_SCOPE __private_extern__" >>confdefs.h
printf "%s\n" "#define MODULE_SCOPE __private_extern__" >>confdefs.h

		tcl_cv_cc_visibility_hidden=yes

fi
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"

$as_echo "#define MAC_OSX_TCL 1" >>confdefs.h
printf "%s\n" "#define MAC_OSX_TCL 1" >>confdefs.h

	    PLAT_OBJS='${MAC_OSX_OBJS}'
	    PLAT_SRCS='${MAC_OSX_SRCS}'
	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use CoreFoundation" >&5
$as_echo_n "checking whether to use CoreFoundation... " >&6; }
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to use CoreFoundation" >&5
printf %s "checking whether to use CoreFoundation... " >&6; }
	    # Check whether --enable-corefoundation was given.
if test "${enable_corefoundation+set}" = set; then :
if test ${enable_corefoundation+y}
then :
  enableval=$enable_corefoundation; tcl_corefoundation=$enableval
else
else $as_nop
  tcl_corefoundation=yes
fi

	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_corefoundation" >&5
$as_echo "$tcl_corefoundation" >&6; }
	    if test $tcl_corefoundation = yes; then :
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_corefoundation" >&5
printf "%s\n" "$tcl_corefoundation" >&6; }
	    if test $tcl_corefoundation = yes
then :

		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CoreFoundation.framework" >&5
$as_echo_n "checking for CoreFoundation.framework... " >&6; }
if ${tcl_cv_lib_corefoundation+:} false; then :
  $as_echo_n "(cached) " >&6
else
		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for CoreFoundation.framework" >&5
printf %s "checking for CoreFoundation.framework... " >&6; }
if test ${tcl_cv_lib_corefoundation+y}
then :
  printf %s "(cached) " >&6
else $as_nop

		    hold_libs=$LIBS
		    if test "$fat_32_64" = yes; then :
		    if test "$fat_32_64" = yes
then :

			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
fi
		    LIBS="$LIBS -framework CoreFoundation"
		    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <CoreFoundation/CoreFoundation.h>
int
main ()
main (void)
{
CFBundleRef b = CFBundleGetMainBundle();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_lib_corefoundation=yes
else
else $as_nop
  tcl_cv_lib_corefoundation=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
		    if test "$fat_32_64" = yes; then :
		    if test "$fat_32_64" = yes
then :

			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    eval $v'="$hold_'$v'"'
		        done
fi
		    LIBS=$hold_libs
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_lib_corefoundation" >&5
$as_echo "$tcl_cv_lib_corefoundation" >&6; }
		if test $tcl_cv_lib_corefoundation = yes; then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_lib_corefoundation" >&5
printf "%s\n" "$tcl_cv_lib_corefoundation" >&6; }
		if test $tcl_cv_lib_corefoundation = yes
then :

		    LIBS="$LIBS -framework CoreFoundation"

$as_echo "#define HAVE_COREFOUNDATION 1" >>confdefs.h
printf "%s\n" "#define HAVE_COREFOUNDATION 1" >>confdefs.h


else
else $as_nop
  tcl_corefoundation=no
fi
		if test "$fat_32_64" = yes -a $tcl_corefoundation = yes; then :
		if test "$fat_32_64" = yes -a $tcl_corefoundation = yes
then :

		    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit CoreFoundation" >&5
$as_echo_n "checking for 64-bit CoreFoundation... " >&6; }
if ${tcl_cv_lib_corefoundation_64+:} false; then :
  $as_echo_n "(cached) " >&6
else
		    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for 64-bit CoreFoundation" >&5
printf %s "checking for 64-bit CoreFoundation... " >&6; }
if test ${tcl_cv_lib_corefoundation_64+y}
then :
  printf %s "(cached) " >&6
else $as_nop

			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
			cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <CoreFoundation/CoreFoundation.h>
int
main ()
main (void)
{
CFBundleRef b = CFBundleGetMainBundle();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_lib_corefoundation_64=yes
else
else $as_nop
  tcl_cv_lib_corefoundation_64=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    eval $v'="$hold_'$v'"'
			done
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_lib_corefoundation_64" >&5
$as_echo "$tcl_cv_lib_corefoundation_64" >&6; }
		    if test $tcl_cv_lib_corefoundation_64 = no; then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_lib_corefoundation_64" >&5
printf "%s\n" "$tcl_cv_lib_corefoundation_64" >&6; }
		    if test $tcl_cv_lib_corefoundation_64 = no
then :


$as_echo "#define NO_COREFOUNDATION_64 1" >>confdefs.h
printf "%s\n" "#define NO_COREFOUNDATION_64 1" >>confdefs.h

                        LDFLAGS="$LDFLAGS -Wl,-no_arch_warnings"

fi

fi

fi
	    ;;
	OS/390-*)
	    SHLIB_LD_LIBS=""
	    CFLAGS_OPTIMIZE=""		# Optimizer is buggy

$as_echo "#define _OE_SOCKETS 1" >>confdefs.h
printf "%s\n" "#define _OE_SOCKETS 1" >>confdefs.h

	    ;;
	OSF1-V*)
	    # Digital OSF/1
	    SHLIB_CFLAGS=""
	    if test "$SHARED_BUILD" = 1; then :
	    if test "$SHARED_BUILD" = 1
then :

	        SHLIB_LD='ld -shared -expect_unresolved "*"'

else
else $as_nop

	        SHLIB_LD='ld -non_shared -expect_unresolved "*"'

fi
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    if test $doRpath = yes; then :
	    if test $doRpath = yes
then :

		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
fi
	    if test "$GCC" = yes; then :
	    if test "$GCC" = yes
then :
  CFLAGS="$CFLAGS -mieee"
else
else $as_nop

		CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"
fi
	    # see pthread_intro(3) for pthread support on osf1, k.furukawa
	    CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
	    CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
	    LIBS=`echo $LIBS | sed s/-lpthreads//`
	    if test "$GCC" = yes; then :
	    if test "$GCC" = yes
then :

		LIBS="$LIBS -lpthread -lmach -lexc"

else
else $as_nop

		CFLAGS="$CFLAGS -pthread"
		LDFLAGS="$LDFLAGS -pthread"

fi
	    ;;
	QNX-6*)
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







-
+
+




-
+




















-
+


-
+






-
+
+





-
+












-
+


-
+





-
+
+


-
+
+

-
+
+

-
+
+

-
-
+
+

-
+








-
+


-
+
+




-
+










-
-
+
+
+

-
+
+







-
-
+
+


-
+













-
-
-
+
+
+









-
+
+

-
+


-
-
-
+
+
+
+

-
-
+
+

-
-
+
+
+


-



-
+

-
-
+
+








-
+
+




-
+
+

-
+
+









-
-
+
+
+








-
+

-
+
+

-
+







	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	SCO_SV-3.2*)
	    # Note, dlopen is available only on SCO 3.2.5 and greater. However,
	    # this test works, since "uname -s" was non-standard in 3.2.4 and
	    # below.
	    if test "$GCC" = yes; then :
	    if test "$GCC" = yes
then :

		SHLIB_CFLAGS="-fPIC -melf"
		LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"

else
else $as_nop

		SHLIB_CFLAGS="-Kpic -belf"
		LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"

fi
	    SHLIB_LD="ld -G"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	SunOS-5.[0-6])
	    # Careful to not let 5.10+ fall into this case

	    # Note: If _REENTRANT isn't defined, then Solaris
	    # won't define thread-safe library routines.


$as_echo "#define _REENTRANT 1" >>confdefs.h
printf "%s\n" "#define _REENTRANT 1" >>confdefs.h


$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
printf "%s\n" "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h


	    SHLIB_CFLAGS="-KPIC"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    if test "$GCC" = yes; then :
	    if test "$GCC" = yes
then :

		SHLIB_LD='${CC} -shared'
		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}

else
else $as_nop

		SHLIB_LD="/usr/ccs/bin/ld -G -z text"
		CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}

fi
	    ;;
	SunOS-5*)
	    # Note: If _REENTRANT isn't defined, then Solaris
	    # won't define thread-safe library routines.


$as_echo "#define _REENTRANT 1" >>confdefs.h
printf "%s\n" "#define _REENTRANT 1" >>confdefs.h


$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
printf "%s\n" "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h


	    SHLIB_CFLAGS="-KPIC"

	    # Check to enable 64-bit flags for compiler/linker
	    if test "$do64bit" = yes; then :
	    if test "$do64bit" = yes
then :

		arch=`isainfo`
		if test "$arch" = "sparcv9 sparc"; then :
		if test "$arch" = "sparcv9 sparc"
then :

		    if test "$GCC" = yes; then :
		    if test "$GCC" = yes
then :

			if test "`${CC} -dumpversion | awk -F. '{print $1}'`" -lt 3; then :
			if test "`${CC} -dumpversion | awk -F. '{print $1}'`" -lt 3
then :

			    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5
$as_echo "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;}
			    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5
printf "%s\n" "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;}

else
else $as_nop

			    do64bit_ok=yes
			    CFLAGS="$CFLAGS -m64 -mcpu=v9"
			    LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
			    SHLIB_CFLAGS="-fPIC"

fi

else
else $as_nop

			do64bit_ok=yes
			if test "$do64bitVIS" = yes; then :
			if test "$do64bitVIS" = yes
then :

			    CFLAGS="$CFLAGS -xarch=v9a"
			    LDFLAGS_ARCH="-xarch=v9a"

else
else $as_nop

			    CFLAGS="$CFLAGS -xarch=v9"
			    LDFLAGS_ARCH="-xarch=v9"

fi
			# Solaris 64 uses this as well
			#LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"

fi

else
  if test "$arch" = "amd64 i386"; then :
else $as_nop
  if test "$arch" = "amd64 i386"
then :

		    if test "$GCC" = yes; then :
		    if test "$GCC" = yes
then :

			case $system in
			    SunOS-5.1[1-9]*|SunOS-5.[2-9][0-9]*)
				do64bit_ok=yes
				CFLAGS="$CFLAGS -m64"
				LDFLAGS="$LDFLAGS -m64";;
			    *)
				{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5
$as_echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;};;
				{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5
printf "%s\n" "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;};;
			esac

else
else $as_nop

			do64bit_ok=yes
			case $system in
			    SunOS-5.1[1-9]*|SunOS-5.[2-9][0-9]*)
				CFLAGS="$CFLAGS -m64"
				LDFLAGS="$LDFLAGS -m64";;
			    *)
				CFLAGS="$CFLAGS -xarch=amd64"
				LDFLAGS="$LDFLAGS -xarch=amd64";;
			esac

fi

else
  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported for $arch" >&5
$as_echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;}
else $as_nop
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported for $arch" >&5
printf "%s\n" "$as_me: WARNING: 64bit mode not supported for $arch" >&2;}
fi
fi

fi

	    #--------------------------------------------------------------------
	    # On Solaris 5.x i386 with the sunpro compiler we need to link
	    # with sunmath to get floating point rounding control
	    #--------------------------------------------------------------------
	    if test "$GCC" = yes; then :
	    if test "$GCC" = yes
then :
  use_sunmath=no
else
else $as_nop

		arch=`isainfo`
		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use -lsunmath for fp rounding control" >&5
$as_echo_n "checking whether to use -lsunmath for fp rounding control... " >&6; }
		if test "$arch" = "amd64 i386" -o "$arch" = "i386"; then :
		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to use -lsunmath for fp rounding control" >&5
printf %s "checking whether to use -lsunmath for fp rounding control... " >&6; }
		if test "$arch" = "amd64 i386" -o "$arch" = "i386"
then :

			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
			{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
			MATH_LIBS="-lsunmath $MATH_LIBS"
			ac_fn_c_check_header_mongrel "$LINENO" "sunmath.h" "ac_cv_header_sunmath_h" "$ac_includes_default"
if test "x$ac_cv_header_sunmath_h" = xyes; then :
			ac_fn_c_check_header_compile "$LINENO" "sunmath.h" "ac_cv_header_sunmath_h" "$ac_includes_default"
if test "x$ac_cv_header_sunmath_h" = xyes
then :

fi


			use_sunmath=yes

else
else $as_nop

			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
			{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
			use_sunmath=no

fi

fi
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    if test "$GCC" = yes; then :
	    if test "$GCC" = yes
then :

		SHLIB_LD='${CC} -shared'
		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
		if test "$do64bit_ok" = yes; then :
		if test "$do64bit_ok" = yes
then :

		    if test "$arch" = "sparcv9 sparc"; then :
		    if test "$arch" = "sparcv9 sparc"
then :

			# We need to specify -static-libgcc or we need to
			# add the path to the sparv9 libgcc.
			SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
			# for finding sparcv9 libgcc, get the regular libgcc
			# path, remove so name and append 'sparcv9'
			#v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
			#CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"

else
  if test "$arch" = "amd64 i386"; then :
else $as_nop
  if test "$arch" = "amd64 i386"
then :

			SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"

fi
fi

fi

else
else $as_nop

		if test "$use_sunmath" = yes; then :
		if test "$use_sunmath" = yes
then :
  textmode=textoff
else
else $as_nop
  textmode=text
fi
		case $system in
		    SunOS-5.[1-9][0-9]*|SunOS-5.[7-9])
			SHLIB_LD="\${CC} -G -z $textmode \${LDFLAGS}";;
		    *)
			SHLIB_LD="/usr/ccs/bin/ld -G -z $textmode";;
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
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







-
-
-
-
-
+
+
+
+
+
+







-
+






-
+
+

-
+


-
+



-
-
-
+
+
+
+









-
+
+

-
-
+
+



-
+
+


-
+









-
+
+

-
+



-
+
+



-
+
+

-
+

-
-
+
+

















-
+
+




-
+




-
+






-
+
+


-
+




-
+
+



-
+
+





-
+
+



-
+
+




-
+





-
+



-
+
+



-
+









-
+
+



-
+









-
+
+









-
-
-
-
-
+
+
+
+
+
+




-
+









-
+
+

-
+


-
+


-
-
+
+


-
+


+
+
+
+
+
+
+
+
+

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

-
+


-







	    SHLIB_LD='${CC} -G'
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    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.
	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld accepts -Bexport flag" >&5
$as_echo_n "checking for ld accepts -Bexport flag... " >&6; }
if ${tcl_cv_ld_Bexport+:} false; then :
  $as_echo_n "(cached) " >&6
else
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld accepts -Bexport flag" >&5
printf %s "checking for ld accepts -Bexport flag... " >&6; }
if test ${tcl_cv_ld_Bexport+y}
then :
  printf %s "(cached) " >&6
else $as_nop

		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -Wl,-Bexport"
		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
main (void)
{
int i;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_ld_Bexport=yes
else
else $as_nop
  tcl_cv_ld_Bexport=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
	        LDFLAGS=$hold_ldflags
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_Bexport" >&5
$as_echo "$tcl_cv_ld_Bexport" >&6; }
	    if test $tcl_cv_ld_Bexport = yes; then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_Bexport" >&5
printf "%s\n" "$tcl_cv_ld_Bexport" >&6; }
	    if test $tcl_cv_ld_Bexport = yes
then :

		LDFLAGS="$LDFLAGS -Wl,-Bexport"

fi
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
    esac

    if test "$do64bit" = yes -a "$do64bit_ok" = no; then :
    if test "$do64bit" = yes -a "$do64bit_ok" = no
then :

	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5
$as_echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;}
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5
printf "%s\n" "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;}

fi

    if test "$do64bit" = yes -a "$do64bit_ok" = yes; then :
    if test "$do64bit" = yes -a "$do64bit_ok" = yes
then :


$as_echo "#define TCL_CFG_DO64BIT 1" >>confdefs.h
printf "%s\n" "#define TCL_CFG_DO64BIT 1" >>confdefs.h


fi



    # Step 4: disable dynamic loading if requested via a command-line switch.

    # Check whether --enable-load was given.
if test "${enable_load+set}" = set; then :
if test ${enable_load+y}
then :
  enableval=$enable_load; tcl_ok=$enableval
else
else $as_nop
  tcl_ok=yes
fi

    if test "$tcl_ok" = no; then :
    if test "$tcl_ok" = no
then :
  DL_OBJS=""
fi

    if test "x$DL_OBJS" != x; then :
    if test "x$DL_OBJS" != x
then :
  BUILD_DLTEST="\$(DLTEST_TARGETS)"
else
else $as_nop

	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&5
$as_echo "$as_me: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&2;}
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&5
printf "%s\n" "$as_me: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&2;}
	SHLIB_CFLAGS=""
	SHLIB_LD=""
	SHLIB_SUFFIX=""
	DL_OBJS="tclLoadNone.o"
	DL_LIBS=""
	LDFLAGS="$LDFLAGS_ORIG"
	CC_SEARCH_FLAGS=""
	LD_SEARCH_FLAGS=""
	BUILD_DLTEST=""

fi
    LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"

    # If we're running gcc, then change the C flags for compiling shared
    # libraries to the right flags for gcc, instead of those for the
    # standard manufacturer compiler.

    if test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes; then :
    if test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes
then :

	case $system in
	    AIX-*) ;;
	    BSD/OS*) ;;
	    CYGWIN_*) ;;
	    CYGWIN_*|MINGW32_*|MSYS_*) ;;
	    HP_UX*) ;;
	    Darwin-*) ;;
	    IRIX*) ;;
	    Linux*|GNU*) ;;
	    NetBSD-*|OpenBSD-*) ;;
	    NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
	    OSF1-V*) ;;
	    SCO_SV-3.2*) ;;
	    *) SHLIB_CFLAGS="-fPIC" ;;
	esac
fi

    if test "$tcl_cv_cc_visibility_hidden" != yes; then :
    if test "$tcl_cv_cc_visibility_hidden" != yes
then :


$as_echo "#define MODULE_SCOPE extern" >>confdefs.h
printf "%s\n" "#define MODULE_SCOPE extern" >>confdefs.h


fi

    if test "$SHARED_LIB_SUFFIX" = ""; then :
    if test "$SHARED_LIB_SUFFIX" = ""
then :

	SHARED_LIB_SUFFIX='${VERSION}${SHLIB_SUFFIX}'
fi
    if test "$UNSHARED_LIB_SUFFIX" = ""; then :
    if test "$UNSHARED_LIB_SUFFIX" = ""
then :

	UNSHARED_LIB_SUFFIX='${VERSION}.a'
fi
    DLL_INSTALL_DIR="\$(LIB_INSTALL_DIR)"

    if test "${SHARED_BUILD}" = 1 -a "${SHLIB_SUFFIX}" != ""; then :
    if test "${SHARED_BUILD}" = 1 -a "${SHLIB_SUFFIX}" != ""
then :

        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}'
        if test "${SHLIB_SUFFIX}" = ".dll"; then :
        if test "${SHLIB_SUFFIX}" = ".dll"
then :

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

else
else $as_nop

            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"'

fi

else
else $as_nop

        LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}

        if test "$RANLIB" = ""; then :
        if test "$RANLIB" = ""
then :

            MAKE_LIB='$(STLIB_LD) $@ ${OBJS}'

else
else $as_nop

            MAKE_LIB='${STLIB_LD} $@ ${OBJS} ; ${RANLIB} $@'

fi
        INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"'

fi

    # Stub lib does not depend on shared/static configuration
    if test "$RANLIB" = ""; then :
    if test "$RANLIB" = ""
then :

        MAKE_STUB_LIB='${STLIB_LD} $@ ${STUB_LIB_OBJS}'

else
else $as_nop

        MAKE_STUB_LIB='${STLIB_LD} $@ ${STUB_LIB_OBJS} ; ${RANLIB} $@'

fi
    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.
    if test "x${TCL_LIBS}" = x; then :
    if test "x${TCL_LIBS}" = x
then :

        TCL_LIBS="${DL_LIBS} ${LIBS} ${MATH_LIBS}"
fi


	# See if the compiler supports casting to a union type.
	# This is used to stop gcc from printing a compiler
	# warning when initializing a union member.

	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cast to union support" >&5
$as_echo_n "checking for cast to union support... " >&6; }
if ${tcl_cv_cast_to_union+:} false; then :
  $as_echo_n "(cached) " >&6
else
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for cast to union support" >&5
printf %s "checking for cast to union support... " >&6; }
if test ${tcl_cv_cast_to_union+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
main (void)
{

		  union foo { int i; double d; };
		  union foo f = (union foo) (int) 0;

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_cast_to_union=yes
else
else $as_nop
  tcl_cv_cast_to_union=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam 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; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cast_to_union" >&5
printf "%s\n" "$tcl_cv_cast_to_union" >&6; }
	if test "$tcl_cv_cast_to_union" = "yes"; then

$as_echo "#define HAVE_CAST_TO_UNION 1" >>confdefs.h
printf "%s\n" "#define HAVE_CAST_TO_UNION 1" >>confdefs.h

	fi
	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -fno-lto"
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working -fno-lto" >&5
printf %s "checking for working -fno-lto... " >&6; }
if test ${ac_cv_nolto+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_nolto=yes
else $as_nop
  ac_cv_nolto=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext

fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_nolto" >&5
printf "%s\n" "$ac_cv_nolto" >&6; }
	CFLAGS=$hold_cflags
	if test "$ac_cv_nolto" = "yes" ; then
	    CFLAGS_NOLTO="-fno-lto"
	else
	    CFLAGS_NOLTO=""
	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 :
    ac_fn_c_check_header_compile "$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
printf "%s\n" "#define HAVE_STDBOOL_H 1" >>confdefs.h

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.


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
6210
6211
6212
6213
6214
6215
6216


6217
6218

6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229


6230
6231
6232

6233
6234
6235

6236
6237
6238
6239
6240
6241
6242
6243
6244

6245
6246


6247
6248
6249

6250
6251
6252
6253
6254
6255


6256
6257
6258
6259
6260
6261
6262
6263
6264

6265
6266
6267
6268
6269
6270
6271
6272


6273
6274
6275


6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286


6287
6288
6289
6290



6291
6292
6293
6294
6295
6296
6297
6298

6299
6300
6301
6302
6303
6304
6305

6306
6307
6308

6309
6310
6311
6312
6313
6314

6315
6316
6317
6318
6319
6320
6321

6322
6323
6324

6325
6326
6327

6328
6329

6330
6331
6332
6333
6334

6335
6336
6337
6338
6339
6340



6341
6342
6343
6344
6345
6346
6347
6348

6349
6350
6351
6352
6353
6354
6355

6356
6357
6358

6359
6360
6361
6362
6363
6364

6365
6366
6367
6368
6369
6370
6371

6372
6373
6374

6375
6376
6377

6378
6379

6380
6381
6382
6383
6384

6385
6386
6387
6388
6389
6390



6391
6392
6393
6394
6395
6396
6397
6398

6399
6400
6401
6402
6403
6404
6405

6406
6407
6408

6409
6410
6411
6412
6413
6414

6415
6416
6417
6418
6419
6420
6421

6422
6423
6424

6425
6426
6427

6428
6429

6430
6431
6432
6433
6434

6435
6436
6437
6438
6439
6440


6441
6442
6443


6444
6445
6446
6447
6448
6449





6450
6451
6452
6453
6454
6455
6456
6457


















6458
6459
6460
6461
6462
6463
6464

6465
6466
6467

6468
6469
6470
6471
6472
6473


6474
6475
6476
6477

6478
6479
6480
6481
6482

6483
6484


6485
6486
6487








6488





6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500

6501
6502
6503
6504
6505
6506
6507

6508
6509
6510

6511
6512
6513

6514
6515


6516
6517
6518
6519

6520
6521
6522
6523





6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535

6536
6537
6538
6539
6540
6541
6542
6543

6544
6545
6546

6547
6548
6549

6550
6551


6552
6553
6554
6555

6556
6557
6558
6559





6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570

6571
6572
6573
6574
6575
6576
6577
6578

6579
6580
6581

6582
6583
6584

6585
6586


6587
6588
6589
6590

6591
6592
6593
6594
6595






6596
6597
6598
6599
6600
6601
6602
6603
6604


6605
6606

6607





6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618

6619
6620
6621
6622
6623
6624
6625
6626

6627
6628
6629

6630
6631
6632

6633
6634
6635
6636
6637
6638
6639

6640
6641


6642
6643
6644


6645
6646
6647
6648
6649
6650
6651
6652
6653
6654





6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670

6671
6672
6673
6674
6675
6676
6677
6678
6679







-
-
+
+
-











-
-
+
+

-
+
+

-
+








-
+

-
-
+
+

-
+





-
-
+
+







-
+







-
-
+
+

-
-
+
+









-
-
+
+


-
-
-
+
+
+
+




-
+






-
+
+

-
+





-
+






-
+
+

-
+


-
+

-
+




-
+





-
-
-
+
+
+
+




-
+






-
+
+

-
+





-
+






-
+
+

-
+


-
+

-
+




-
+





-
-
-
+
+
+
+




-
+






-
+
+

-
+





-
+






-
+
+

-
+


-
+

-
+




-
+





-
-
+
+

-
-
+
+




-
-
-
-
-
+
+
+
+
+
+


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







-
+


-
+





-
-
+
+
+

-
+




-
+

-
-
+
+

-
-
-
-
-
-
-
-

-
-
-
-
-
+
+
+
+
+
+






-
+






-
+
+

-
+


-
+

-
-
+
+


-
+



-
-
-
-
-
+
+
+
+
+
+






-
+







-
+
+

-
+


-
+

-
-
+
+


-
+



-
-
-
-
-
+
+
+
+
+
+





-
+







-
+
+

-
+


-
+

-
-
+
+


-
+



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


-

-
-
-
-
-
+
+
+
+
+
+





-
+







-
+
+

-
+


-
+






-
+

-
-
+
+

-
-
+
+








-
-
-
-
-
+
+
+
+
+
+










-
+
+














cat >>confdefs.h <<_ACEOF
#define TCL_SHLIB_EXT "${SHLIB_SUFFIX}"

printf "%s\n" "#define TCL_SHLIB_EXT \"${SHLIB_SUFFIX}\"" >>confdefs.h
_ACEOF











    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build with symbols" >&5
$as_echo_n "checking for build with symbols... " >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build with symbols" >&5
printf %s "checking for build with symbols... " >&6; }
    # Check whether --enable-symbols was given.
if test "${enable_symbols+set}" = set; then :
if test ${enable_symbols+y}
then :
  enableval=$enable_symbols; tcl_ok=$enableval
else
else $as_nop
  tcl_ok=no
fi

# FIXME: Currently, LDFLAGS_DEFAULT is not used, it should work like CFLAGS_DEFAULT.
    if test "$tcl_ok" = "no"; then
	CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)'
	LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'

$as_echo "#define NDEBUG 1" >>confdefs.h
printf "%s\n" "#define NDEBUG 1" >>confdefs.h

	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }

$as_echo "#define TCL_CFG_OPTIMIZED 1" >>confdefs.h
printf "%s\n" "#define TCL_CFG_OPTIMIZED 1" >>confdefs.h

    else
	CFLAGS_DEFAULT='$(CFLAGS_DEBUG)'
	LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)'
	if test "$tcl_ok" = "yes"; then
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (standard debugging)" >&5
$as_echo "yes (standard debugging)" >&6; }
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes (standard debugging)" >&5
printf "%s\n" "yes (standard debugging)" >&6; }
	fi
    fi



    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then

$as_echo "#define TCL_MEM_DEBUG 1" >>confdefs.h
printf "%s\n" "#define TCL_MEM_DEBUG 1" >>confdefs.h

    fi



    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
	if test "$tcl_ok" = "all"; then
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled symbols mem debugging" >&5
$as_echo "enabled symbols mem debugging" >&6; }
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: enabled symbols mem debugging" >&5
printf "%s\n" "enabled symbols mem debugging" >&6; }
	else
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled $tcl_ok debugging" >&5
$as_echo "enabled $tcl_ok debugging" >&6; }
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: enabled $tcl_ok debugging" >&5
printf "%s\n" "enabled $tcl_ok debugging" >&6; }
	fi
    fi


#--------------------------------------------------------------------
#	Detect what compiler flags to set for 64-bit support.
#--------------------------------------------------------------------


    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for required early compiler flags" >&5
$as_echo_n "checking for required early compiler flags... " >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for required early compiler flags" >&5
printf %s "checking for required early compiler flags... " >&6; }
    tcl_flags=""

    if ${tcl_cv_flag__isoc99_source+:} false; then :
  $as_echo_n "(cached) " >&6
else
    if test ${tcl_cv_flag__isoc99_source+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <stdlib.h>
int
main ()
main (void)
{
char *p = (char *)strtoll; char *q = (char *)strtoull;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_flag__isoc99_source=no
else
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#define _ISOC99_SOURCE 1
#include <stdlib.h>
int
main ()
main (void)
{
char *p = (char *)strtoll; char *q = (char *)strtoull;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_flag__isoc99_source=yes
else
else $as_nop
  tcl_cv_flag__isoc99_source=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi

    if test "x${tcl_cv_flag__isoc99_source}" = "xyes" ; then

$as_echo "#define _ISOC99_SOURCE 1" >>confdefs.h
printf "%s\n" "#define _ISOC99_SOURCE 1" >>confdefs.h

	tcl_flags="$tcl_flags _ISOC99_SOURCE"
    fi


    if ${tcl_cv_flag__largefile64_source+:} false; then :
  $as_echo_n "(cached) " >&6
else
    if test ${tcl_cv_flag__largefile64_source+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/stat.h>
int
main ()
main (void)
{
struct stat64 buf; int i = stat64("/", &buf);
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_flag__largefile64_source=no
else
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#define _LARGEFILE64_SOURCE 1
#include <sys/stat.h>
int
main ()
main (void)
{
struct stat64 buf; int i = stat64("/", &buf);
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_flag__largefile64_source=yes
else
else $as_nop
  tcl_cv_flag__largefile64_source=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi

    if test "x${tcl_cv_flag__largefile64_source}" = "xyes" ; then

$as_echo "#define _LARGEFILE64_SOURCE 1" >>confdefs.h
printf "%s\n" "#define _LARGEFILE64_SOURCE 1" >>confdefs.h

	tcl_flags="$tcl_flags _LARGEFILE64_SOURCE"
    fi


    if ${tcl_cv_flag__largefile_source64+:} false; then :
  $as_echo_n "(cached) " >&6
else
    if test ${tcl_cv_flag__largefile_source64+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/stat.h>
int
main ()
main (void)
{
char *p = (char *)open64;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_flag__largefile_source64=no
else
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#define _LARGEFILE_SOURCE64 1
#include <sys/stat.h>
int
main ()
main (void)
{
char *p = (char *)open64;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_flag__largefile_source64=yes
else
else $as_nop
  tcl_cv_flag__largefile_source64=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi

    if test "x${tcl_cv_flag__largefile_source64}" = "xyes" ; then

$as_echo "#define _LARGEFILE_SOURCE64 1" >>confdefs.h
printf "%s\n" "#define _LARGEFILE_SOURCE64 1" >>confdefs.h

	tcl_flags="$tcl_flags _LARGEFILE_SOURCE64"
    fi

    if test "x${tcl_flags}" = "x" ; then
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
$as_echo "none" >&6; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5
printf "%s\n" "none" >&6; }
    else
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${tcl_flags}" >&5
$as_echo "${tcl_flags}" >&6; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${tcl_flags}" >&5
printf "%s\n" "${tcl_flags}" >&6; }
    fi



    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit integer type" >&5
$as_echo_n "checking for 64-bit integer type... " >&6; }
    if ${tcl_cv_type_64bit+:} false; then :
  $as_echo_n "(cached) " >&6
else
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for 64-bit integer type" >&5
printf %s "checking for 64-bit integer type... " >&6; }
    if test ${tcl_cv_type_64bit+y}
then :
  printf %s "(cached) " >&6
else $as_nop

	tcl_cv_type_64bit=none
	# See if the compiler knows natively about __int64
	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{
__int64 value = (__int64) 0;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
  tcl_type_64bit=__int64
else
  tcl_type_64bit="long long"
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
	# See if we could use long anyway  Note that we substitute in the
	# type that is our current guess for a 64-bit type inside this check
	# program, so it should be modified only carefully...
        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
main (void)
{
switch (0) {
            case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ;
            case 1: case (sizeof(long long)==sizeof(long)): ;
        }
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
  tcl_cv_type_64bit=${tcl_type_64bit}
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_type_64bit="long long"
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi

    if test "${tcl_cv_type_64bit}" = none ; then

$as_echo "#define TCL_WIDE_INT_IS_LONG 1" >>confdefs.h
printf "%s\n" "#define TCL_WIDE_INT_IS_LONG 1" >>confdefs.h

	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
    else

cat >>confdefs.h <<_ACEOF
#define TCL_WIDE_INT_TYPE ${tcl_cv_type_64bit}
_ACEOF

	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${tcl_cv_type_64bit}" >&5
$as_echo "${tcl_cv_type_64bit}" >&6; }

	# Now check for auxiliary declarations
	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct dirent64" >&5
$as_echo_n "checking for struct dirent64... " >&6; }
if ${tcl_cv_struct_dirent64+:} false; then :
  $as_echo_n "(cached) " >&6
else
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for struct dirent64" >&5
printf %s "checking for struct dirent64... " >&6; }
if test ${tcl_cv_struct_dirent64+y}
then :
  printf %s "(cached) " >&6
else $as_nop

	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/types.h>
#include <dirent.h>
int
main ()
main (void)
{
struct dirent64 p;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_struct_dirent64=yes
else
else $as_nop
  tcl_cv_struct_dirent64=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_struct_dirent64" >&5
$as_echo "$tcl_cv_struct_dirent64" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_struct_dirent64" >&5
printf "%s\n" "$tcl_cv_struct_dirent64" >&6; }
	if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then

$as_echo "#define HAVE_STRUCT_DIRENT64 1" >>confdefs.h
printf "%s\n" "#define HAVE_STRUCT_DIRENT64 1" >>confdefs.h

	fi

	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DIR64" >&5
$as_echo_n "checking for DIR64... " >&6; }
if ${tcl_cv_DIR64+:} false; then :
  $as_echo_n "(cached) " >&6
else
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for DIR64" >&5
printf %s "checking for DIR64... " >&6; }
if test ${tcl_cv_DIR64+y}
then :
  printf %s "(cached) " >&6
else $as_nop

	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/types.h>
#include <dirent.h>
int
main ()
main (void)
{
struct dirent64 *p; DIR64 d = opendir64(".");
            p = readdir64(d); rewinddir64(d); closedir64(d);
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_DIR64=yes
else
else $as_nop
  tcl_cv_DIR64=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_DIR64" >&5
$as_echo "$tcl_cv_DIR64" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_DIR64" >&5
printf "%s\n" "$tcl_cv_DIR64" >&6; }
	if test "x${tcl_cv_DIR64}" = "xyes" ; then

$as_echo "#define HAVE_DIR64 1" >>confdefs.h
printf "%s\n" "#define HAVE_DIR64 1" >>confdefs.h

	fi

	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct stat64" >&5
$as_echo_n "checking for struct stat64... " >&6; }
if ${tcl_cv_struct_stat64+:} false; then :
  $as_echo_n "(cached) " >&6
else
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for struct stat64" >&5
printf %s "checking for struct stat64... " >&6; }
if test ${tcl_cv_struct_stat64+y}
then :
  printf %s "(cached) " >&6
else $as_nop

	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/stat.h>
int
main ()
main (void)
{
struct stat64 p;

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_struct_stat64=yes
else
else $as_nop
  tcl_cv_struct_stat64=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_struct_stat64" >&5
$as_echo "$tcl_cv_struct_stat64" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_struct_stat64" >&5
printf "%s\n" "$tcl_cv_struct_stat64" >&6; }
	if test "x${tcl_cv_struct_stat64}" = "xyes" ; then

$as_echo "#define HAVE_STRUCT_STAT64 1" >>confdefs.h
printf "%s\n" "#define HAVE_STRUCT_STAT64 1" >>confdefs.h

	fi

	ac_fn_c_check_func "$LINENO" "open64" "ac_cv_func_open64"
	for ac_func in open64 lseek64
do :
  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
  cat >>confdefs.h <<_ACEOF
if test "x$ac_cv_func_open64" = xyes
then :
  printf "%s\n" "#define HAVE_OPEN64 1" >>confdefs.h

fi
ac_fn_c_check_func "$LINENO" "lseek64" "ac_cv_func_lseek64"
if test "x$ac_cv_func_lseek64" = xyes
then :
  printf "%s\n" "#define HAVE_LSEEK64 1" >>confdefs.h
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF

fi
done

	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for off64_t" >&5
$as_echo_n "checking for off64_t... " >&6; }
	if ${tcl_cv_type_off64_t+:} false; then :
  $as_echo_n "(cached) " >&6
else
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for off64_t" >&5
printf %s "checking for off64_t... " >&6; }
	if test ${tcl_cv_type_off64_t+y}
then :
  printf %s "(cached) " >&6
else $as_nop

	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/types.h>
int
main ()
main (void)
{
off64_t offset;

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_type_off64_t=yes
else
else $as_nop
  tcl_cv_type_off64_t=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi

			if test "x${tcl_cv_type_off64_t}" = "xyes" && \
	        test "x${ac_cv_func_lseek64}" = "xyes" && \
	        test "x${ac_cv_func_open64}" = "xyes" ; then

$as_echo "#define HAVE_TYPE_OFF64_T 1" >>confdefs.h
printf "%s\n" "#define HAVE_TYPE_OFF64_T 1" >>confdefs.h

	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
	else
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
	fi
    fi


#--------------------------------------------------------------------
#	Check endianness because we can optimize some operations
#--------------------------------------------------------------------

 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
if ${ac_cv_c_bigendian+:} false; then :
  $as_echo_n "(cached) " >&6
else
 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
printf %s "checking whether byte ordering is bigendian... " >&6; }
if test ${ac_cv_c_bigendian+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  ac_cv_c_bigendian=unknown
    # See if we're dealing with a universal compiler.
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#ifndef __APPLE_CC__
	       not a universal capable compiler
	     #endif
	     typedef int dummy;

_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :

	# Check for potential -arch flags.  It is not universal unless
	# there are at least two -arch flags with different values.
	ac_arch=
	ac_prev=
	for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
	 if test -n "$ac_prev"; then
6400
6401
6402
6403
6404
6405
6406
6407

6408
6409
6410
6411
6412
6413
6414
6415
6416

6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428


6429
6430
6431
6432
6433
6434
6435
6436

6437
6438
6439
6440
6441
6442
6443
6444
6445
6446


6447
6448

6449
6450
6451

6452
6453

6454
6455
6456
6457
6458
6459
6460
6461
6462

6463
6464
6465
6466
6467
6468
6469
6470
6471
6472


6473
6474
6475
6476
6477
6478
6479

6480
6481
6482
6483
6484
6485
6486
6487
6488
6489


6490
6491

6492
6493
6494

6495
6496

6497
6498
6499
6500


6501
6502
6503
6504

6505
6506

6507
6508
6509
6510
6511

6512
6513

6514
6515
6516
6517
6518
6519
6520
6521

6522
6523
6524
6525
6526
6527
6528


6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542


6543
6544
6545
6546
6547

6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563


6564
6565

6566
6567
6568
6569
6570
6571
6572
6573
6574
6575


6576
6577
6578

6579
6580
6581
6582
6583
6584

6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605

6606
6607
6608


6609
6610

6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627






6628
6629
6630
6631
6632
6633

6634
6635
6636
6637
6638
6639
6640


6641
6642

6643
6644
6645

6646
6647
6648


6649
6650





































































































































6651
6652
6653
6654



































































































































6655
















6656
6657
6658
6659
6660
6661
6662
6663


6664
6665

6666
6667
6668

6669
6670
6671
6672


6673
6674
6675

6676
6677
6678
6679
6680
6681
6682

6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744


6745
6746

6747
6748
6749

6750
6751
6752
6753

6754
6755




6756
6757



6758



6759
6760









6761







6762



6763

6764
6765
6766
6767


6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780

6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793

6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807

6808
6809

6810
6811
6812

6813
6814

6815
6816
6817
6818
6819
6820

6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850

6851
6852
6853
6854
6855
6856
6857
6858

6859
6860

6861
6862
6863

6864
6865

6866
6867
6868
6869
6870
6871

6872
6873
6874
6875
6876
6877
6878
6879
6880

6881
6882
6883
6884
6885


6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919






6920
6921
6922
6923
6924
6925

6926
6927

6928
6929
6930
6931
6932


6933
6934

6935
6936
6937

6938
6939
6940


6941
6942
6943

6944
6945
6946
6947
6948
6949
6950
6951
6952
6953


6954
6955


6956
6957

6958
6959
6960
6961
6962
6963
6964
6965


6966
6967
6968
6969
6970


6971
6972
6973
6974
6975


6976
6977
6978
6979
6980


6981
6982
6983
6984
6985
6986
6987






6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998

6999
7000
7001
7002
7003
7004
7005


7006
7007

7008
7009
7010

7011
7012
7013
7014
7015
7016
7017


7018
7019
7020
7021
7022
7023


7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035






7036
7037
7038
7039
7040
7041
7042
7043

7044
7045
7046
7047
7048
7049
7050


7051
7052

7053
7054
7055

7056
7057
7058
7059
7060


7061
7062
7063
7064
7065


7066
7067


7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079






7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095

7096
7097
7098
7099
7100
7101
7102


7103
7104

7105
7106
7107

7108
7109
7110
7111
7112


7113
7114
7115

7116
7117
7118
7119
7120
7121
7122






7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139

7140
7141
7142
7143
7144
7145
7146


7147
7148

7149
7150
7151

7152
7153
7154
7155


7156
7157
7158

7159
7160
7161
7162
7163
7164
7165
7166
7167
7168

7169
7170




7171
7172
7173
7174
7175

7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190


7191
7192
7193
7194


7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207




7208
7209
7210






























7211
7212
7213
7214
7215
7216
7217
6689
6690
6691
6692
6693
6694
6695

6696
6697
6698
6699
6700
6701
6702
6703
6704

6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716

6717
6718
6719
6720
6721
6722
6723
6724
6725

6726
6727
6728
6729
6730
6731
6732
6733
6734
6735

6736
6737
6738

6739
6740
6741

6742
6743

6744
6745
6746
6747
6748
6749
6750
6751
6752

6753
6754
6755
6756
6757
6758
6759
6760
6761
6762

6763
6764
6765
6766
6767
6768
6769
6770

6771
6772
6773
6774
6775
6776
6777
6778
6779
6780

6781
6782
6783

6784
6785
6786

6787
6788

6789
6790
6791
6792

6793
6794
6795
6796
6797

6798
6799

6800
6801
6802
6803
6804

6805
6806

6807
6808
6809
6810
6811
6812
6813
6814

6815
6816
6817
6818
6819
6820
6821

6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835


6836
6837
6838
6839
6840
6841

6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857

6858
6859
6860

6861
6862
6863
6864
6865
6866
6867
6868
6869


6870
6871
6872
6873

6874
6875
6876
6877
6878
6879

6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900

6901
6902


6903
6904
6905

6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918





6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929

6930
6931
6932
6933
6934
6935
6936

6937
6938
6939

6940
6941
6942

6943
6944


6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081




7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236

7237
7238
7239

7240
7241
7242

7243
7244
7245


7246
7247
7248
7249

7250
7251
7252
7253
7254
7255
7256

7257
7258
7259
7260
7261
7262
7263
7264







7265






































7266
7267
7268
7269
7270
7271
7272
7273

7274
7275
7276

7277
7278


7279

7280
7281
7282
7283


7284
7285
7286
7287
7288

7289
7290
7291
7292
7293
7294
7295


7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320


7321
7322

7323











7324



7325









7326




7327





7328
7329
7330

7331


7332
7333


7334


7335






7336




























7337

7338


7339

7340
7341


7342


7343
7344


7345


7346






7347









7348





7349
7350





















7351
7352
7353
7354
7355
7356
7357
7358





7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369

7370
7371

7372
7373
7374
7375
7376

7377
7378
7379

7380
7381
7382

7383
7384


7385
7386
7387
7388

7389
7390
7391
7392
7393
7394
7395
7396
7397


7398
7399
7400

7401
7402
7403

7404
7405
7406
7407
7408
7409
7410


7411
7412
7413
7414
7415


7416
7417
7418
7419
7420


7421
7422
7423
7424
7425


7426
7427
7428
7429





7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445

7446
7447
7448
7449
7450
7451
7452

7453
7454
7455

7456
7457
7458

7459
7460
7461
7462
7463
7464


7465
7466
7467
7468
7469
7470


7471
7472
7473
7474
7475
7476
7477
7478
7479





7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492

7493
7494
7495
7496
7497
7498
7499

7500
7501
7502

7503
7504
7505

7506
7507
7508
7509


7510
7511
7512




7513
7514


7515
7516

7517
7518
7519


7520





7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541

7542
7543
7544
7545
7546
7547
7548

7549
7550
7551

7552
7553
7554

7555
7556
7557
7558


7559
7560
7561
7562

7563
7564
7565





7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587

7588
7589
7590
7591
7592
7593
7594

7595
7596
7597

7598
7599
7600

7601
7602
7603


7604
7605
7606
7607

7608
7609
7610
7611
7612
7613
7614
7615
7616
7617

7618
7619

7620
7621
7622
7623
7624
7625
7626
7627

7628
7629
7630
7631
7632
7633
7634
7635
7636
7637
7638
7639
7640
7641


7642
7643
7644
7645
7646

7647
7648
7649
7650
7651
7652
7653
7654
7655
7656
7657
7658



7659
7660
7661
7662
7663


7664
7665
7666
7667
7668
7669
7670
7671
7672
7673
7674
7675
7676
7677
7678
7679
7680
7681
7682
7683
7684
7685
7686
7687
7688
7689
7690
7691
7692
7693
7694
7695
7696
7697
7698
7699
7700







-
+








-
+











-
+
+







-
+









-
+
+

-
+


-
+

-
+








-
+









-
+
+






-
+









-
+
+

-
+


-
+

-
+



-
+
+



-
+

-
+




-
+

-
+







-
+






-
+
+












-
-
+
+




-
+















-
+
+

-
+








-
-
+
+


-
+





-
+




















-
+

-
-
+
+

-
+












-
-
-
-
-
+
+
+
+
+
+





-
+






-
+
+

-
+


-
+

-
-
+
+


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

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







-
+
+

-
+


-
+


-
-
+
+


-
+






-
+







-
-
-
-
-
-
-

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








-
+
+

-
+

-
-
+
-



+
-
-
+
+
+
+

-
+
+
+

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

+
+
+
+
+
+
+

+
+
+

+


-
-
+
+
-

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

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

-
-
-
-
-



-
+
-
-
+

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

-
+
-
-

-


-
-
+
-
-
+

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








-
-
-
-
-
+
+
+
+
+
+





-
+

-
+




-
+
+

-
+


-
+

-
-
+
+


-
+








-
-
+
+

-
+
+

-
+






-
-
+
+



-
-
+
+



-
-
+
+



-
-
+
+


-
-
-
-
-
+
+
+
+
+
+










-
+






-
+
+

-
+


-
+





-
-
+
+




-
-
+
+







-
-
-
-
-
+
+
+
+
+
+







-
+






-
+
+

-
+


-
+



-
-
+
+

-
-
-
-
+
+
-
-
+
+
-



-
-

-
-
-
-
-
+
+
+
+
+
+















-
+






-
+
+

-
+


-
+



-
-
+
+


-
+


-
-
-
-
-
+
+
+
+
+
+
















-
+






-
+
+

-
+


-
+


-
-
+
+


-
+









-
+

-
+
+
+
+




-
+













-
-
+
+



-
+
+










-
-
-
+
+
+
+

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







	   esac
	   ac_prev=
	 elif test "x$ac_word" = "x-arch"; then
	   ac_prev=arch
	 fi
       done
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    if test $ac_cv_c_bigendian = unknown; then
      # See if sys/param.h defines the BYTE_ORDER macro.
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/types.h>
	     #include <sys/param.h>

int
main ()
main (void)
{
#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
		     && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
		     && LITTLE_ENDIAN)
	      bogus endian macros
	     #endif

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  # It does; now see whether it defined to BIG_ENDIAN or not.
	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/types.h>
		#include <sys/param.h>

int
main ()
main (void)
{
#if BYTE_ORDER != BIG_ENDIAN
		 not big endian
		#endif

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_c_bigendian=yes
else
else $as_nop
  ac_cv_c_bigendian=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    fi
    if test $ac_cv_c_bigendian = unknown; then
      # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <limits.h>

int
main ()
main (void)
{
#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
	      bogus endian macros
	     #endif

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  # It does; now see whether it defined to _BIG_ENDIAN or not.
	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <limits.h>

int
main ()
main (void)
{
#ifndef _BIG_ENDIAN
		 not big endian
		#endif

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_c_bigendian=yes
else
else $as_nop
  ac_cv_c_bigendian=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    fi
    if test $ac_cv_c_bigendian = unknown; then
      # Compile a test program.
      if test "$cross_compiling" = yes; then :
      if test "$cross_compiling" = yes
then :
  # Try to guess by grepping values from an object file.
	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
short int ascii_mm[] =
unsigned short int ascii_mm[] =
		  { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
		short int ascii_ii[] =
		unsigned short int ascii_ii[] =
		  { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
		int use_ascii (int i) {
		  return ascii_mm[i] + ascii_ii[i];
		}
		short int ebcdic_ii[] =
		unsigned short int ebcdic_ii[] =
		  { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
		short int ebcdic_mm[] =
		unsigned short int ebcdic_mm[] =
		  { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
		int use_ebcdic (int i) {
		  return ebcdic_mm[i] + ebcdic_ii[i];
		}
		extern int foo;

int
main ()
main (void)
{
return use_ascii (foo) == use_ebcdic (foo);
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
	      ac_cv_c_bigendian=yes
	    fi
	    if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
	      if test "$ac_cv_c_bigendian" = unknown; then
		ac_cv_c_bigendian=no
	      else
		# finding both strings is unlikely to happen, but who knows?
		ac_cv_c_bigendian=unknown
	      fi
	    fi
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
else
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$ac_includes_default
int
main ()
main (void)
{

	     /* Are we little or big endian?  From Harbison&Steele.  */
	     union
	     {
	       long int l;
	       char c[sizeof (long int)];
	     } u;
	     u.l = 1;
	     return u.c[sizeof (long int) - 1] == 1;

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
if ac_fn_c_try_run "$LINENO"
then :
  ac_cv_c_bigendian=no
else
else $as_nop
  ac_cv_c_bigendian=yes
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
  conftest.$ac_objext conftest.beam conftest.$ac_ext
fi

    fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
$as_echo "$ac_cv_c_bigendian" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
printf "%s\n" "$ac_cv_c_bigendian" >&6; }
 case $ac_cv_c_bigendian in #(
   yes)
     $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
     printf "%s\n" "#define WORDS_BIGENDIAN 1" >>confdefs.h
;; #(
   no)
      ;; #(
   universal)

$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
printf "%s\n" "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h

     ;; #(
   *)
     as_fn_error $? "unknown endianness
 presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
 esac


#------------------------------------------------------------------------
# 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
    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING:
        Different --prefix selected for Tk and Tcl!
        [package require Tk] may not work correctly in tclsh." >&5
$as_echo "$as_me: WARNING:
        [package require tk] may not work correctly in tclsh." >&5
printf "%s\n" "$as_me: WARNING:
        Different --prefix selected for Tk and Tcl!
        [package require Tk] may not work correctly in tclsh." >&2;}
        [package require tk] may not work correctly in tclsh." >&2;}
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.
#--------------------------------------------------------------------

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fd_set in sys/types" >&5
$as_echo_n "checking for fd_set in sys/types... " >&6; }
if ${tcl_cv_type_fd_set+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fd_set in sys/types" >&5
printf %s "checking for fd_set in sys/types... " >&6; }
if test ${tcl_cv_type_fd_set+y}
then :
  printf %s "(cached) " >&6
else $as_nop

    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/types.h>
int
main ()
main (void)
{
fd_set readMask, writeMask;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_type_fd_set=yes
else
else $as_nop
  tcl_cv_type_fd_set=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_type_fd_set" >&5
$as_echo "$tcl_cv_type_fd_set" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_type_fd_set" >&5
printf "%s\n" "$tcl_cv_type_fd_set" >&6; }
tk_ok=$tcl_cv_type_fd_set
if test $tk_ok = no; then
    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
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
printf %s "checking how to run the C preprocessor... " >&6; }
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
  CPP=
fi
if test -z "$CPP"; then
  if test ${ac_cv_prog_CPP+y}
then :
  printf %s "(cached) " >&6
else $as_nop
      # Double quotes because $CC needs to be expanded
    for CPP in "$CC -E" "$CC -E -traditional-cpp" 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.
  # On the NeXT, cc -E runs the code through the compiler's parser,
  # not just through cpp. "Syntax error" is here to catch this case.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <limits.h>
		     Syntax error
_ACEOF
if ac_fn_c_try_cpp "$LINENO"
then :

else $as_nop
  # Broken: fails on valid input.
continue
fi
rm -f conftest.err conftest.i conftest.$ac_ext

  # OK, works on sane cases.  Now check whether nonexistent headers
  # can be detected and how.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <ac_nonexistent.h>
_ACEOF
if ac_fn_c_try_cpp "$LINENO"
then :
  # Broken: success on invalid input.
continue
else $as_nop
  # Passes both tests.
ac_preproc_ok=:
break
fi
rm -f conftest.err conftest.i conftest.$ac_ext

done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
rm -f conftest.i conftest.err conftest.$ac_ext
if $ac_preproc_ok
then :
  break
fi

    done
    ac_cv_prog_CPP=$CPP

fi
  CPP=$ac_cv_prog_CPP
else
  ac_cv_prog_CPP=$CPP
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
printf "%s\n" "$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.
  # On the NeXT, cc -E runs the code through the compiler's parser,
  # not just through cpp. "Syntax error" is here to catch this case.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <limits.h>
		     Syntax error
_ACEOF
if ac_fn_c_try_cpp "$LINENO"
then :

else $as_nop
  # Broken: fails on valid input.
continue
fi
rm -f conftest.err conftest.i conftest.$ac_ext

  # OK, works on sane cases.  Now check whether nonexistent headers
  # can be detected and how.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <ac_nonexistent.h>
_ACEOF
if ac_fn_c_try_cpp "$LINENO"
then :
  # Broken: success on invalid input.
continue
else $as_nop
  # Passes both tests.
ac_preproc_ok=:
break
fi
rm -f conftest.err conftest.i conftest.$ac_ext

done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
rm -f conftest.i conftest.err conftest.$ac_ext
if $ac_preproc_ok
then :

else $as_nop
  { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
See \`config.log' for more details" "$LINENO" 5; }
fi

ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu


    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fd_mask in sys/select" >&5
$as_echo_n "checking for fd_mask in sys/select... " >&6; }
if ${tcl_cv_grep_fd_mask+:} false; then :
  $as_echo_n "(cached) " >&6
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
printf %s "checking for grep that handles long lines and -e... " >&6; }
if test ${ac_cv_path_GREP+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    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
  printf %s 0123456789 >"conftest.in"
  while :
  do
    cat "conftest.in" "conftest.in" >"conftest.tmp"
    mv "conftest.tmp" "conftest.in"
    cp "conftest.in" "conftest.nl"
    printf "%s\n" 'GREP' >> "conftest.nl"
    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
    as_fn_arith $ac_count + 1 && ac_count=$as_val
    if test $ac_count -gt ${ac_path_GREP_max-0}; then
      # Best one so far, save it but keep looking for a better one
      ac_cv_path_GREP="$ac_path_GREP"
      ac_path_GREP_max=$ac_count
    fi
    # 10*(2^10) chars as input seems more than enough
    test $ac_count -gt 10 && break
  done
  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
esac

      $ac_path_GREP_found && break 3
    done
  done
  done
IFS=$as_save_IFS
  if test -z "$ac_cv_path_GREP"; then
    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
  fi
else
  ac_cv_path_GREP=$GREP
fi

fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
printf "%s\n" "$ac_cv_path_GREP" >&6; }
 GREP="$ac_cv_path_GREP"


{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
printf %s "checking for egrep... " >&6; }
if test ${ac_cv_path_EGREP+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    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
  printf %s 0123456789 >"conftest.in"
  while :
  do
    cat "conftest.in" "conftest.in" >"conftest.tmp"
    mv "conftest.tmp" "conftest.in"
    cp "conftest.in" "conftest.nl"
    printf "%s\n" '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
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
printf "%s\n" "$ac_cv_path_EGREP" >&6; }
 EGREP="$ac_cv_path_EGREP"


{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fd_mask in sys/select" >&5
printf %s "checking for fd_mask in sys/select... " >&6; }
if test ${tcl_cv_grep_fd_mask+y}
then :
  printf %s "(cached) " >&6
else $as_nop

	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/select.h>

_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  $EGREP "fd_mask" >/dev/null 2>&1; then :
  $EGREP "fd_mask" >/dev/null 2>&1
then :
  tcl_cv_grep_fd_mask=present
else
else $as_nop
  tcl_cv_grep_fd_mask=missing
fi
rm -f conftest*
rm -rf conftest*

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_grep_fd_mask" >&5
$as_echo "$tcl_cv_grep_fd_mask" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_grep_fd_mask" >&5
printf "%s\n" "$tcl_cv_grep_fd_mask" >&6; }
    if test $tcl_cv_grep_fd_mask = present; then

$as_echo "#define HAVE_SYS_SELECT_H 1" >>confdefs.h
printf "%s\n" "#define HAVE_SYS_SELECT_H 1" >>confdefs.h

	tk_ok=yes
    fi
fi
if test $tk_ok = no; then

$as_echo "#define NO_FD_SET 1" >>confdefs.h
printf "%s\n" "#define NO_FD_SET 1" >>confdefs.h

fi

#------------------------------------------------------------------------------
#       Find out all about time handling differences.
#------------------------------------------------------------------------------

for ac_header in sys/time.h
do :
  ac_fn_c_check_header_mongrel "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default"
if test "x$ac_cv_header_sys_time_h" = xyes; then :
  cat >>confdefs.h <<_ACEOF
#define HAVE_SYS_TIME_H 1
_ACEOF

fi

done

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
if ${ac_cv_header_time+:} false; then :
  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>

int
main ()
{
if ((struct tm *) 0)
return 0;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
  ac_cv_header_time=yes
else
  ac_cv_header_time=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
$as_echo "$ac_cv_header_time" >&6; }
if test $ac_cv_header_time = yes; then

$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h

fi


#--------------------------------------------------------------------
#	Check for various typedefs and provide substitutes if
#	they don't exist.
#--------------------------------------------------------------------

ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default"
if test "x$ac_cv_type_mode_t" = xyes; then :
if test "x$ac_cv_type_mode_t" = xyes
then :

else
else $as_nop

cat >>confdefs.h <<_ACEOF
#define mode_t int
printf "%s\n" "#define mode_t int" >>confdefs.h
_ACEOF

fi


ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
if test "x$ac_cv_type_pid_t" = xyes; then :
  ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default
"
if test "x$ac_cv_type_pid_t" = xyes
then :

else
else $as_nop
                                          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

          #if defined _WIN64 && !defined __CYGWIN__
          LLP64
          #endif
cat >>confdefs.h <<_ACEOF
#define pid_t int

int
main (void)
{

  ;
  return 0;
}

_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  ac_pid_type='int'
else $as_nop
  ac_pid_type='__int64'
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext

printf "%s\n" "#define pid_t $ac_pid_type" >>confdefs.h


fi


ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
if test "x$ac_cv_type_size_t" = xyes; then :

if test "x$ac_cv_type_size_t" = xyes
then :
else

cat >>confdefs.h <<_ACEOF
#define size_t unsigned int
_ACEOF

fi

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5
$as_echo_n "checking for uid_t in sys/types.h... " >&6; }
if ${ac_cv_type_uid_t+:} false; then :
  $as_echo_n "(cached) " >&6
else
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/types.h>

_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  $EGREP "uid_t" >/dev/null 2>&1; then :
  ac_cv_type_uid_t=yes
else
  ac_cv_type_uid_t=no
fi
rm -f conftest*

printf "%s\n" "#define size_t unsigned int" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5
$as_echo "$ac_cv_type_uid_t" >&6; }
if test $ac_cv_type_uid_t = no; then

$as_echo "#define uid_t int" >>confdefs.h


$as_echo "#define gid_t int" >>confdefs.h

fi


ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default"
ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "
if test "x$ac_cv_type_intptr_t" = xyes; then :

#include <stdint.h>

$as_echo "#define HAVE_INTPTR_T 1" >>confdefs.h

"
else

if test "x$ac_cv_type_intptr_t" = xyes
    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pointer-size signed integer type" >&5
$as_echo_n "checking for pointer-size signed integer type... " >&6; }
if ${tcl_cv_intptr_t+:} false; then :
  $as_echo_n "(cached) " >&6
else

then :
    for tcl_cv_intptr_t in "int" "long" "long long" none; do
	if test "$tcl_cv_intptr_t" != none; then
	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* 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 test_array [0];

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
  tcl_ok=yes
else
  tcl_ok=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
	    test "$tcl_ok" = yes && break; fi
    done
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_intptr_t" >&5
$as_echo "$tcl_cv_intptr_t" >&6; }
    if test "$tcl_cv_intptr_t" != none; then

cat >>confdefs.h <<_ACEOF
printf "%s\n" "#define HAVE_INTPTR_T 1" >>confdefs.h
#define intptr_t $tcl_cv_intptr_t
_ACEOF

    fi

fi

ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default"
ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "
if test "x$ac_cv_type_uintptr_t" = xyes; then :

#include <stdint.h>

$as_echo "#define HAVE_UINTPTR_T 1" >>confdefs.h

"
else

if test "x$ac_cv_type_uintptr_t" = xyes
    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pointer-size unsigned integer type" >&5
$as_echo_n "checking for pointer-size unsigned integer type... " >&6; }
if ${tcl_cv_uintptr_t+:} false; then :
  $as_echo_n "(cached) " >&6
else

then :
    for tcl_cv_uintptr_t in "unsigned int" "unsigned long" "unsigned long long" \
	    none; do
	if test "$tcl_cv_uintptr_t" != none; then
	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* 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 test_array [0];

  ;
printf "%s\n" "#define HAVE_UINTPTR_T 1" >>confdefs.h

  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
  tcl_ok=yes
else
  tcl_ok=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
	    test "$tcl_ok" = yes && break; fi
    done
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_uintptr_t" >&5
$as_echo "$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


#-------------------------------------------
#     In OS/390 struct pwd has no pw_gecos field
#-------------------------------------------

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking pw_gecos in struct pwd" >&5
$as_echo_n "checking pw_gecos in struct pwd... " >&6; }
if ${tcl_cv_pwd_pw_gecos+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking pw_gecos in struct pwd" >&5
printf %s "checking pw_gecos in struct pwd... " >&6; }
if test ${tcl_cv_pwd_pw_gecos+y}
then :
  printf %s "(cached) " >&6
else $as_nop

    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <pwd.h>
int
main ()
main (void)
{
struct passwd pwd; pwd.pw_gecos;
struct passwd pwd; (void)pwd.pw_gecos;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_pwd_pw_gecos=yes
else
else $as_nop
  tcl_cv_pwd_pw_gecos=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_pwd_pw_gecos" >&5
$as_echo "$tcl_cv_pwd_pw_gecos" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_pwd_pw_gecos" >&5
printf "%s\n" "$tcl_cv_pwd_pw_gecos" >&6; }
if test $tcl_cv_pwd_pw_gecos = yes; then

$as_echo "#define HAVE_PW_GECOS 1" >>confdefs.h
printf "%s\n" "#define HAVE_PW_GECOS 1" >>confdefs.h

fi

#--------------------------------------------------------------------
#	On Mac OS X, we can build either with X11 or with Aqua
#--------------------------------------------------------------------

if test "`uname -s`" = "Darwin" ; then
    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use Aqua" >&5
$as_echo_n "checking whether to use Aqua... " >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to use Aqua" >&5
printf %s "checking whether to use Aqua... " >&6; }
    # Check whether --enable-aqua was given.
if test "${enable_aqua+set}" = set; then :
if test ${enable_aqua+y}
then :
  enableval=$enable_aqua; tk_aqua=$enableval
else
else $as_nop
  tk_aqua=no
fi

    if test $tk_aqua = yes -o $tk_aqua = cocoa; then
	tk_aqua=yes
	if test $tcl_corefoundation = no; then
	    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Aqua can only be used when CoreFoundation is available" >&5
$as_echo "$as_me: WARNING: Aqua can only be used when CoreFoundation is available" >&2;}
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Aqua can only be used when CoreFoundation is available" >&5
printf "%s\n" "$as_me: WARNING: Aqua can only be used when CoreFoundation is available" >&2;}
	    tk_aqua=no
	fi
	if test ! -d /System/Library/Frameworks/Cocoa.framework; then
	    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Aqua can only be used when Cocoa is available" >&5
$as_echo "$as_me: WARNING: Aqua can only be used when Cocoa is available" >&2;}
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Aqua can only be used when Cocoa is available" >&5
printf "%s\n" "$as_me: WARNING: Aqua can only be used when Cocoa is available" >&2;}
	    tk_aqua=no
	fi
	if test "`uname -r | awk -F. '{print $1}'`" -lt 9; then
	    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Aqua requires Mac OS X 10.5 or later" >&5
$as_echo "$as_me: WARNING: Aqua requires Mac OS X 10.5 or later" >&2;}
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Aqua requires Mac OS X 10.5 or later" >&5
printf "%s\n" "$as_me: WARNING: Aqua requires Mac OS X 10.5 or later" >&2;}
	    tk_aqua=no
	fi
    fi
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tk_aqua" >&5
$as_echo "$tk_aqua" >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tk_aqua" >&5
printf "%s\n" "$tk_aqua" >&6; }
    if test "$fat_32_64" = yes; then
	if test $tk_aqua = no; then
	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit X11" >&5
$as_echo_n "checking for 64-bit X11... " >&6; }
if ${tcl_cv_lib_x11_64+:} false; then :
  $as_echo_n "(cached) " >&6
else
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for 64-bit X11" >&5
printf %s "checking for 64-bit X11... " >&6; }
if test ${tcl_cv_lib_x11_64+y}
then :
  printf %s "(cached) " >&6
else $as_nop

		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"
		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <X11/Xlib.h>
int
main ()
main (void)
{
XrmInitialize();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_lib_x11_64=yes
else
else $as_nop
  tcl_cv_lib_x11_64=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
		for v in CFLAGS CPPFLAGS LDFLAGS; do
		    eval $v'="$hold_'$v'"'
		done
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_lib_x11_64" >&5
$as_echo "$tcl_cv_lib_x11_64" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_lib_x11_64" >&5
printf "%s\n" "$tcl_cv_lib_x11_64" >&6; }
	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
	    { $as_echo "$as_me:${as_lineno-$LINENO}: Removing 64-bit architectures from compiler & linker flags" >&5
$as_echo "$as_me: Removing 64-bit architectures from compiler & linker flags" >&6;}
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Removing 64-bit architectures from compiler & linker flags" >&5
printf "%s\n" "$as_me: Removing 64-bit architectures from compiler & linker flags" >&6;}
	    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.
	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if ld accepts -weak-l flag" >&5
$as_echo_n "checking if ld accepts -weak-l flag... " >&6; }
if ${tcl_cv_ld_weak_l+:} false; then :
  $as_echo_n "(cached) " >&6
else
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if ld accepts -weak-l flag" >&5
printf %s "checking if ld accepts -weak-l flag... " >&6; }
if test ${tcl_cv_ld_weak_l+y}
then :
  printf %s "(cached) " >&6
else $as_nop

	    hold_ldflags=$LDFLAGS
	    LDFLAGS="$LDFLAGS -Wl,-weak-lm"
	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <math.h>
int
main ()
main (void)
{
double f = sin(1.0);
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_ld_weak_l=yes
else
else $as_nop
  tcl_cv_ld_weak_l=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
	    LDFLAGS=$hold_ldflags
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_weak_l" >&5
$as_echo "$tcl_cv_ld_weak_l" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_weak_l" >&5
printf "%s\n" "$tcl_cv_ld_weak_l" >&6; }
    fi
    for ac_header in AvailabilityMacros.h
do :
  ac_fn_c_check_header_mongrel "$LINENO" "AvailabilityMacros.h" "ac_cv_header_AvailabilityMacros_h" "$ac_includes_default"
if test "x$ac_cv_header_AvailabilityMacros_h" = xyes; then :
    ac_fn_c_check_header_compile "$LINENO" "AvailabilityMacros.h" "ac_cv_header_AvailabilityMacros_h" "$ac_includes_default"
if test "x$ac_cv_header_AvailabilityMacros_h" = xyes
  cat >>confdefs.h <<_ACEOF
#define HAVE_AVAILABILITYMACROS_H 1
then :
  printf "%s\n" "#define HAVE_AVAILABILITYMACROS_H 1" >>confdefs.h
_ACEOF

fi

done

    if test "$ac_cv_header_AvailabilityMacros_h" = yes; then
	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if weak import is available" >&5
$as_echo_n "checking if weak import is available... " >&6; }
if ${tcl_cv_cc_weak_import+:} false; then :
  $as_echo_n "(cached) " >&6
else
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if weak import is available" >&5
printf %s "checking if weak import is available... " >&6; }
if test ${tcl_cv_cc_weak_import+y}
then :
  printf %s "(cached) " >&6
else $as_nop

	    hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

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

int
main ()
main (void)
{
rand();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_cc_weak_import=yes
else
else $as_nop
  tcl_cv_cc_weak_import=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
	    CFLAGS=$hold_cflags
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_weak_import" >&5
$as_echo "$tcl_cv_cc_weak_import" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_weak_import" >&5
printf "%s\n" "$tcl_cv_cc_weak_import" >&6; }
	if test $tcl_cv_cc_weak_import = yes; then

$as_echo "#define HAVE_WEAK_IMPORT 1" >>confdefs.h
printf "%s\n" "#define HAVE_WEAK_IMPORT 1" >>confdefs.h

	fi
	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if Darwin SUSv3 extensions are available" >&5
$as_echo_n "checking if Darwin SUSv3 extensions are available... " >&6; }
if ${tcl_cv_cc_darwin_c_source+:} false; then :
  $as_echo_n "(cached) " >&6
else
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if Darwin SUSv3 extensions are available" >&5
printf %s "checking if Darwin SUSv3 extensions are available... " >&6; }
if test ${tcl_cv_cc_darwin_c_source+y}
then :
  printf %s "(cached) " >&6
else $as_nop

	    hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

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

int
main ()
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_cc_darwin_c_source=yes
else
else $as_nop
  tcl_cv_cc_darwin_c_source=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
	    CFLAGS=$hold_cflags
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_darwin_c_source" >&5
$as_echo "$tcl_cv_cc_darwin_c_source" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_darwin_c_source" >&5
printf "%s\n" "$tcl_cv_cc_darwin_c_source" >&6; }
	if test $tcl_cv_cc_darwin_c_source = yes; then

$as_echo "#define _DARWIN_C_SOURCE 1" >>confdefs.h
printf "%s\n" "#define _DARWIN_C_SOURCE 1" >>confdefs.h

	fi
    fi
else
    tk_aqua=no
fi

if test $tk_aqua = yes; then

$as_echo "#define MAC_OSX_TK 1" >>confdefs.h
printf "%s\n" "#define MAC_OSX_TK 1" >>confdefs.h

    LIBS="$LIBS -framework Cocoa -framework Carbon -framework IOKit"
    LIBS="$LIBS -framework Cocoa -framework Carbon -framework IOKit -framework Security"
    if test -d /System/Library/Frameworks/UserNotifications.framework; then
        LIBS="$LIBS -framework UserNotifications"
    fi
    EXTRA_CC_SWITCHES='-std=gnu99 -x objective-c'
    TK_WINDOWINGSYSTEM=AQUA
    if test -n "${enable_symbols}" -a "${enable_symbols}" != no; then

$as_echo "#define TK_MAC_DEBUG 1" >>confdefs.h
printf "%s\n" "#define TK_MAC_DEBUG 1" >>confdefs.h

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


    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5
$as_echo_n "checking for X... " >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for X" >&5
printf %s "checking for X... " >&6; }


# Check whether --with-x was given.
if test "${with_x+set}" = set; then :
if test ${with_x+y}
then :
  withval=$with_x;
fi

# $have_x is `yes', `no', `disabled', or empty when we do not yet know.
if test "x$with_x" = xno; then
  # The user explicitly disabled X.
  have_x=disabled
else
  case $x_includes,$x_libraries in #(
    *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #(
    *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then :
  $as_echo_n "(cached) " >&6
else
    *,NONE | NONE,*) if test ${ac_cv_have_x+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  # One or both of the vars are not set, and there is no cached value.
ac_x_includes=no ac_x_libraries=no
rm -f -r conftest.dir
ac_x_includes=no
ac_x_libraries=no
# Do we need to do anything special at all?
ac_save_LIBS=$LIBS
LIBS="-lX11 $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <X11/Xlib.h>
int
main (void)
{
XrmInitialize ()
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  # We can compile and link X programs with no special options.
  ac_x_includes=
  ac_x_libraries=
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS="$ac_save_LIBS"
# If that didn't work, only try xmkmf and file system searches
# for native compilation.
if test x"$ac_x_includes" = xno && test "$cross_compiling" = no
then :
  rm -f -r conftest.dir
if mkdir conftest.dir; then
  cd conftest.dir
  cat >Imakefile <<'_ACEOF'
incroot:
	@echo incroot='${INCROOT}'
usrlibdir:
	@echo usrlibdir='${USRLIBDIR}'
7242
7243
7244
7245
7246
7247
7248
7249

7250
7251
7252
7253
7254
7255
7256
7725
7726
7727
7728
7729
7730
7731

7732
7733
7734
7735
7736
7737
7738
7739







-
+







	*) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;;
    esac
  fi
  cd ..
  rm -f -r conftest.dir
fi

# Standard set of common directories for X headers.
  # Standard set of common directories for X headers.
# Check X11 before X11Rn because it is often a symlink to the current release.
ac_x_header_dirs='
/usr/X11/include
/usr/X11R7/include
/usr/X11R6/include
/usr/X11R5/include
/usr/X11R4/include
7268
7269
7270
7271
7272
7273
7274


7275
7276
7277
7278
7279
7280
7281
7751
7752
7753
7754
7755
7756
7757
7758
7759
7760
7761
7762
7763
7764
7765
7766







+
+







/usr/local/X11R4/include

/usr/local/include/X11
/usr/local/include/X11R7
/usr/local/include/X11R6
/usr/local/include/X11R5
/usr/local/include/X11R4

/opt/X11/include

/usr/X386/include
/usr/x386/include
/usr/XFree86/include/X11

/usr/include
/usr/local/include
7290
7291
7292
7293
7294
7295
7296
7297


7298
7299
7300

7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321

7322
7323
7324
7325
7326
7327
7328


7329
7330
7331
7332

7333
7334

7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345

7346
7347
7348


7349
7350

7351
7352
7353


7354
7355
7356
7357

7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368


7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379


7380
7381
7382
7383
7384
7385
7386
7387
7388
7389


7390
7391

7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403


7404
7405
7406
7407
7408
7409


7410
7411

7412
7413
7414
7415
7416
7417
7418
7419
7420


7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435


7436
7437
7438
7439
7440


7441
7442
7443
7444
7445
7446


7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464






7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478

7479
7480
7481
7482
7483
7484
7485


7486
7487

7488
7489
7490

7491
7492
7493
7494
7495
7496




7497
7498
7499
7500
7501
7502
7503


7504
7505
7506
7507
7508
7509
7510
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







-
+
+


-
+




















-
+






-
+
+



-
+

-
+










-
+



+
+

-
+

-
-
+
+



-
+









-
-
+
+









-
-
+
+









-
+
+

-
+










-
-
+
+





-
+
+

-
+







-
-
+
+













-
-
+
+



-
-
+
+




-
-
+
+













-
-
-
-
-
+
+
+
+
+
+








-
-
-


-
+






-
+
+

-
+


-
+



-
-
-
+
+
+
+





-
-
+
+







if test "$ac_x_includes" = no; then
  # Guess where to find include files, by looking for Xlib.h.
  # First, try using that file with no special directory specified.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <X11/Xlib.h>
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :
if ac_fn_c_try_cpp "$LINENO"
then :
  # We can compile using X headers with no special include directory.
ac_x_includes=
else
else $as_nop
  for ac_dir in $ac_x_header_dirs; do
  if test -r "$ac_dir/X11/Xlib.h"; then
    ac_x_includes=$ac_dir
    break
  fi
done
fi
rm -f conftest.err conftest.i conftest.$ac_ext
fi # $ac_x_includes = no

if test "$ac_x_libraries" = no; then
  # Check for the libraries.
  # See if we find them without any special options.
  # Don't add to $LIBS permanently.
  ac_save_LIBS=$LIBS
  LIBS="-lX11 $LIBS"
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <X11/Xlib.h>
int
main ()
main (void)
{
XrmInitialize ()
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  LIBS=$ac_save_LIBS
# We can link X programs with no special library path.
ac_x_libraries=
else
else $as_nop
  LIBS=$ac_save_LIBS
for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g`
for ac_dir in `printf "%s\n" "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g`
do
  # Don't even attempt the hair of trying to link an X program!
  for ac_extension in a so sl dylib la dll; do
    if test -r "$ac_dir/libX11.$ac_extension"; then
      ac_x_libraries=$ac_dir
      break 2
    fi
  done
done
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
fi # $ac_x_libraries = no

fi
# Record the results.
case $ac_x_includes,$ac_x_libraries in #(
  no,* | *,no | *\'*)
  no,* | *,no | *\'*) :
    # Didn't find X, or a directory has "'" in its name.
    ac_cv_have_x="have_x=no";; #(
  *)
    ac_cv_have_x="have_x=no" ;; #(
  *) :
    # Record where we found X for the cache.
    ac_cv_have_x="have_x=yes\
	ac_x_includes='$ac_x_includes'\
	ac_x_libraries='$ac_x_libraries'"
	ac_x_libraries='$ac_x_libraries'" ;;
esac
fi
;; #(
    *) have_x=yes;;
  esac
  eval "$ac_cv_have_x"
fi # $with_x != no

if test "$have_x" != yes; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5
$as_echo "$have_x" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5
printf "%s\n" "$have_x" >&6; }
  no_x=yes
else
  # If each of the values was on the command line, it overrides each guess.
  test "x$x_includes" = xNONE && x_includes=$ac_x_includes
  test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries
  # Update the cache value to reflect the command line values.
  ac_cv_have_x="have_x=yes\
	ac_x_includes='$x_includes'\
	ac_x_libraries='$x_libraries'"
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5
$as_echo "libraries $x_libraries, headers $x_includes" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5
printf "%s\n" "libraries $x_libraries, headers $x_includes" >&6; }
fi

    not_really_there=""
    if test "$no_x" = ""; then
	if test "$x_includes" = ""; then
	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <X11/Xlib.h>
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :
if ac_fn_c_try_cpp "$LINENO"
then :

else
else $as_nop
  not_really_there="yes"
fi
rm -f conftest.err conftest.i conftest.$ac_ext
	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
	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X11 header files" >&5
$as_echo_n "checking for X11 header files... " >&6; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for X11 header files" >&5
printf %s "checking for X11 header files... " >&6; }
	found_xincludes="no"
	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <X11/Xlib.h>
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :
if ac_fn_c_try_cpp "$LINENO"
then :
  found_xincludes="yes"
else
else $as_nop
  found_xincludes="no"
fi
rm -f conftest.err conftest.i conftest.$ac_ext
	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
		    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $i" >&5
$as_echo "$i" >&6; }
		    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $i" >&5
printf "%s\n" "$i" >&6; }
		    XINCLUDES=" -I$i"
		    found_xincludes="yes"
		    break
		fi
	    done
	fi
    else
	if test "$x_includes" != ""; then
	    XINCLUDES="-I$x_includes"
	    found_xincludes="yes"
	fi
    fi
    if test "$found_xincludes" = "no"; then
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: couldn't find any!" >&5
$as_echo "couldn't find any!" >&6; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: couldn't find any!" >&5
printf "%s\n" "couldn't find any!" >&6; }
    fi

    if test "$no_x" = yes; then
	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X11 libraries" >&5
$as_echo_n "checking for X11 libraries... " >&6; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for X11 libraries" >&5
printf %s "checking for X11 libraries... " >&6; }
	XLIBSW=nope
	dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
	for i in $dirs ; do
	    if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then
		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $i" >&5
$as_echo "$i" >&6; }
		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $i" >&5
printf "%s\n" "$i" >&6; }
		XLIBSW="-L$i -lX11"
		x_libraries="$i"
		break
	    fi
	done
    else
	if test "$x_libraries" = ""; then
	    XLIBSW=-lX11
	else
	    XLIBSW="-L$x_libraries -lX11"
	fi
    fi
    if test "$XLIBSW" = nope ; then
	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for XCreateWindow in -lXwindow" >&5
$as_echo_n "checking for XCreateWindow in -lXwindow... " >&6; }
if ${ac_cv_lib_Xwindow_XCreateWindow+:} false; then :
  $as_echo_n "(cached) " >&6
else
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for XCreateWindow in -lXwindow" >&5
printf %s "checking for XCreateWindow in -lXwindow... " >&6; }
if test ${ac_cv_lib_Xwindow_XCreateWindow+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  ac_check_lib_save_LIBS=$LIBS
LIBS="-lXwindow  $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

/* Override any GCC internal prototype to avoid an error.
   Use char because int might match the return type of a GCC
   builtin and then its argument prototype would still apply.  */
#ifdef __cplusplus
extern "C"
#endif
char XCreateWindow ();
int
main ()
main (void)
{
return XCreateWindow ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_lib_Xwindow_XCreateWindow=yes
else
else $as_nop
  ac_cv_lib_Xwindow_XCreateWindow=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xwindow_XCreateWindow" >&5
$as_echo "$ac_cv_lib_Xwindow_XCreateWindow" >&6; }
if test "x$ac_cv_lib_Xwindow_XCreateWindow" = xyes; then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xwindow_XCreateWindow" >&5
printf "%s\n" "$ac_cv_lib_Xwindow_XCreateWindow" >&6; }
if test "x$ac_cv_lib_Xwindow_XCreateWindow" = xyes
then :
  XLIBSW=-lXwindow
fi

    fi
    if test "$XLIBSW" = nope ; then
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: could not find any!  Using -lX11." >&5
$as_echo "could not find any!  Using -lX11." >&6; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: could not find any!  Using -lX11." >&5
printf "%s\n" "could not find any!  Using -lX11." >&6; }
	XLIBSW=-lX11
    fi

    TK_WINDOWINGSYSTEM=X11
fi

#--------------------------------------------------------------------
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556






7557
7558
7559
7560
7561
7562
7563
7564

7565
7566
7567
7568
7569
7570
7571


7572
7573

7574
7575
7576

7577
7578
7579
7580
7581
7582




7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601


7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612

7613
7614
7615
7616
7617
7618
7619
7620
7621


7622
7623
7624


7625
7626
7627
7628
7629
7630



7631
7632

7633
7634
7635
7636
7637
7638
7639
7640
7641
7642
7643
7644


7645
7646


7647
7648

7649
7650
7651
7652
7653
7654
7655
7656


7657
7658
7659
7660
7661
7662
7663
7664
7665
7666
7667


7668
7669
7670
7671
7672
7673
7674
7675


7676
7677

7678
7679
7680
7681
7682
7683
7684
7685
7686
7687
7688
7689
7690
7691
7692
7693
7694
7695
7696






7697
7698
7699
7700
7701
7702
7703
7704
7705
7706
7707
7708
7709
7710

7711
7712
7713
7714
7715
7716
7717


7718
7719

7720
7721
7722

7723
7724
7725
7726
7727
7728
7729
7730





7731
7732
7733
7734
7735

7736
7737
7738
7739
7740
7741
7742
7743
7744
7745
7746
7747
7748
7749
7750
7751
7752
7753






7754
7755
7756
7757
7758
7759
7760
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
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
8256



8257
8258

8259
8260
8261
8262
8263
8264
8265

8266
8267
8268

8269
8270
8271

8272
8273
8274
8275



8276
8277
8278
8279
8280
8281
8282
8283
8284
8285
8286
8287
8288
8289


8290
8291
8292
8293
8294
8295
8296
8297
8298
8299
8300
8301
8302

8303
8304
8305
8306
8307
8308
8309
8310







-
-
-
-
-
+
+
+
+
+
+







-
+






-
+
+

-
+


-
+



-
-
-
+
+
+
+

















-
-
+
+










-
+








-
+
+

-
-
+
+



-
-
-
+
+
+

-
+










-
-
+
+

-
+
+

-
+






-
-
+
+









-
-
+
+







-
+
+

-
+




-









-
-
-
-
-
+
+
+
+
+
+








-
-
-


-
+






-
+
+

-
+


-
+



-
-
-
-
-
+
+
+
+
+
-



-
+













-
-
-
-
-
+
+
+
+
+
+








-
-
-


-
+






-
+
+

-
+


-
+



-
-
-
+
+
+
+










-
-
+
+











-
+







#	   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
    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lXbsd" >&5
$as_echo_n "checking for main in -lXbsd... " >&6; }
if ${ac_cv_lib_Xbsd_main+:} false; then :
  $as_echo_n "(cached) " >&6
else
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for main in -lXbsd" >&5
printf %s "checking for main in -lXbsd... " >&6; }
if test ${ac_cv_lib_Xbsd_main+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  ac_check_lib_save_LIBS=$LIBS
LIBS="-lXbsd  $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */


int
main ()
main (void)
{
return main ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_lib_Xbsd_main=yes
else
else $as_nop
  ac_cv_lib_Xbsd_main=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xbsd_main" >&5
$as_echo "$ac_cv_lib_Xbsd_main" >&6; }
if test "x$ac_cv_lib_Xbsd_main" = xyes; then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xbsd_main" >&5
printf "%s\n" "$ac_cv_lib_Xbsd_main" >&6; }
if test "x$ac_cv_lib_Xbsd_main" = xyes
then :
  LIBS="$LIBS -lXbsd"
fi

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
    { $as_echo "$as_me:${as_lineno-$LINENO}: checking MIT X libraries" >&5
$as_echo_n "checking MIT X libraries... " >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking MIT X libraries" >&5
printf %s "checking MIT X libraries... " >&6; }
    tk_oldCFlags=$CFLAGS
    CFLAGS="$CFLAGS -I/usr/include/mit"
    tk_oldLibs=$LIBS
    LIBS="$LIBS -lX11-mit"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

	#include <X11/Xlib.h>

int
main ()
main (void)
{

	XOpenDisplay(0);

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :

	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
	XLIBSW="-lX11-mit"
	XINCLUDES="-I/usr/include/mit"

else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
else $as_nop
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
    CFLAGS=$tk_oldCFlags
    LIBS=$tk_oldLibs
fi

#--------------------------------------------------------------------
#	Check for freetype / fontconfig / Xft support.
#--------------------------------------------------------------------

if test $tk_aqua = no; then
    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use xft" >&5
$as_echo_n "checking whether to use xft... " >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to use xft" >&5
printf %s "checking whether to use xft... " >&6; }
    # Check whether --enable-xft was given.
if test "${enable_xft+set}" = set; then :
if test ${enable_xft+y}
then :
  enableval=$enable_xft; enable_xft=$enableval
else
else $as_nop
  enable_xft="default"
fi

    XFT_CFLAGS=""
    XFT_LIBS=""
    if test "$enable_xft" = "no" ; then
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_xft" >&5
$as_echo "$enable_xft" >&6; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_xft" >&5
printf "%s\n" "$enable_xft" >&6; }
    else
	found_xft="yes"
			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
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $found_xft" >&5
$as_echo "$found_xft" >&6; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $found_xft" >&5
printf "%s\n" "$found_xft" >&6; }
		if test "$found_xft" = "yes" ; then
	    tk_oldCFlags=$CFLAGS
	    CFLAGS="$CFLAGS $XINCLUDES $XFT_CFLAGS"
	    tk_oldLibs=$LIBS
	    LIBS="$tk_oldLIBS $XFT_LIBS $XLIBSW"
	    ac_fn_c_check_header_compile "$LINENO" "X11/Xft/Xft.h" "ac_cv_header_X11_Xft_Xft_h" "#include <X11/Xlib.h>
"
if test "x$ac_cv_header_X11_Xft_Xft_h" = xyes; then :
if test "x$ac_cv_header_X11_Xft_Xft_h" = xyes
then :

else
else $as_nop

		found_xft=no

fi


	    CFLAGS=$tk_oldCFlags
	    LIBS=$tk_oldLibs
	fi
		if test "$found_xft" = "yes" ; then
	    tk_oldCFlags=$CFLAGS
	    CFLAGS="$CFLAGS $XINCLUDES $XFT_CFLAGS"
	    tk_oldLibs=$LIBS
	    LIBS="$tk_oldLIBS $XFT_LIBS $XLIBSW"
	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XftFontOpen in -lXft" >&5
$as_echo_n "checking for XftFontOpen in -lXft... " >&6; }
if ${ac_cv_lib_Xft_XftFontOpen+:} false; then :
  $as_echo_n "(cached) " >&6
else
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for XftFontOpen in -lXft" >&5
printf %s "checking for XftFontOpen in -lXft... " >&6; }
if test ${ac_cv_lib_Xft_XftFontOpen+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  ac_check_lib_save_LIBS=$LIBS
LIBS="-lXft  $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

/* Override any GCC internal prototype to avoid an error.
   Use char because int might match the return type of a GCC
   builtin and then its argument prototype would still apply.  */
#ifdef __cplusplus
extern "C"
#endif
char XftFontOpen ();
int
main ()
main (void)
{
return XftFontOpen ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_lib_Xft_XftFontOpen=yes
else
else $as_nop
  ac_cv_lib_Xft_XftFontOpen=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xft_XftFontOpen" >&5
$as_echo "$ac_cv_lib_Xft_XftFontOpen" >&6; }
if test "x$ac_cv_lib_Xft_XftFontOpen" = xyes; then :
  cat >>confdefs.h <<_ACEOF
#define HAVE_LIBXFT 1
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xft_XftFontOpen" >&5
printf "%s\n" "$ac_cv_lib_Xft_XftFontOpen" >&6; }
if test "x$ac_cv_lib_Xft_XftFontOpen" = xyes
then :
  printf "%s\n" "#define HAVE_LIBXFT 1" >>confdefs.h
_ACEOF

  LIBS="-lXft $LIBS"

else
else $as_nop

		found_xft=no

fi

	    CFLAGS=$tk_oldCFlags
	    LIBS=$tk_oldLibs
	fi
		if test "$found_xft" = "yes" ; then
	    tk_oldCFlags=$CFLAGS
	    CFLAGS="$CFLAGS $XINCLUDES $XFT_CFLAGS"
	    tk_oldLibs=$LIBS
	    LIBS="$tk_oldLIBS $XFT_LIBS $XLIBSW -lfontconfig"
	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FcFontSort in -lfontconfig" >&5
$as_echo_n "checking for FcFontSort in -lfontconfig... " >&6; }
if ${ac_cv_lib_fontconfig_FcFontSort+:} false; then :
  $as_echo_n "(cached) " >&6
else
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for FcFontSort in -lfontconfig" >&5
printf %s "checking for FcFontSort in -lfontconfig... " >&6; }
if test ${ac_cv_lib_fontconfig_FcFontSort+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  ac_check_lib_save_LIBS=$LIBS
LIBS="-lfontconfig  $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

/* Override any GCC internal prototype to avoid an error.
   Use char because int might match the return type of a GCC
   builtin and then its argument prototype would still apply.  */
#ifdef __cplusplus
extern "C"
#endif
char FcFontSort ();
int
main ()
main (void)
{
return FcFontSort ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_lib_fontconfig_FcFontSort=yes
else
else $as_nop
  ac_cv_lib_fontconfig_FcFontSort=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_fontconfig_FcFontSort" >&5
$as_echo "$ac_cv_lib_fontconfig_FcFontSort" >&6; }
if test "x$ac_cv_lib_fontconfig_FcFontSort" = xyes; then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_fontconfig_FcFontSort" >&5
printf "%s\n" "$ac_cv_lib_fontconfig_FcFontSort" >&6; }
if test "x$ac_cv_lib_fontconfig_FcFontSort" = xyes
then :

		XFT_LIBS="$XFT_LIBS -lfontconfig"

fi

	    CFLAGS=$tk_oldCFlags
	    LIBS=$tk_oldLibs
	fi
		if test "$found_xft" = "no" ; then
	    if test "$enable_xft" = "yes" ; then
		{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Can't find xft configuration, or xft is unusable" >&5
$as_echo "$as_me: WARNING: Can't find xft configuration, or xft is unusable" >&2;}
		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Can't find xft configuration, or xft is unusable" >&5
printf "%s\n" "$as_me: WARNING: Can't find xft configuration, or xft is unusable" >&2;}
	    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

$as_echo "#define HAVE_XFT 1" >>confdefs.h
printf "%s\n" "#define HAVE_XFT 1" >>confdefs.h

    else
	UNIX_FONT_OBJS=tkUnixFont.o
    fi



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
8322
8323
8324
8325
8326
8327
8328


8329
8330
8331

8332
8333
8334

8335
8336
8337
8338
8339


8340
8341
8342


8343
8344
8345
8346

8347
8348
8349
8350
8351
8352
8353

8354

8355
8356
8357

8358
8359





8360
8361
8362
8363
8364
8365
8366
8367
8368
8369
8370
8371
8372
8373



8374
8375

8376
8377
8378
8379
8380
8381
8382

8383
8384
8385

8386
8387
8388

8389
8390
8391
8392



8393
8394
8395
8396
8397
8398
8399
8400

8401
8402





8403
8404
8405
8406
8407
8408
8409
8410
8411
8412
8413
8414
8415
8416



8417
8418

8419
8420
8421
8422
8423
8424
8425

8426
8427
8428

8429
8430
8431

8432
8433
8434
8435



8436
8437
8438
8439
8440
8441
8442
8443
8444
8445
8446







-
-
+
+

-
+
+

-
+




-
-
+
+

-
-
+
+


-
+
+





-

-
+
+

-
+

-
-
-
-
-
+
+
+
+
+
+








-
-
-


-
+






-
+
+

-
+


-
+



-
-
-
+
+
+
+




-
+

-
-
-
-
-
+
+
+
+
+
+








-
-
-


-
+






-
+
+

-
+


-
+



-
-
-
+
+
+
+







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
    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to try to use XScreenSaver" >&5
$as_echo_n "checking whether to try to use XScreenSaver... " >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to try to use XScreenSaver" >&5
printf %s "checking whether to try to use XScreenSaver... " >&6; }
    # Check whether --enable-xss was given.
if test "${enable_xss+set}" = set; then :
if test ${enable_xss+y}
then :
  enableval=$enable_xss; enable_xss=$enableval
else
else $as_nop
  enable_xss=yes
fi

    if test "$enable_xss" = "no" ; then
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_xss" >&5
$as_echo "$enable_xss" >&6; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_xss" >&5
printf "%s\n" "$enable_xss" >&6; }
    else
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_xss" >&5
$as_echo "$enable_xss" >&6; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_xss" >&5
printf "%s\n" "$enable_xss" >&6; }
	ac_fn_c_check_header_compile "$LINENO" "X11/extensions/scrnsaver.h" "ac_cv_header_X11_extensions_scrnsaver_h" "#include <X11/Xlib.h>
"
if test "x$ac_cv_header_X11_extensions_scrnsaver_h" = xyes; then :
if test "x$ac_cv_header_X11_extensions_scrnsaver_h" = xyes
then :

	    xss_header_found=yes

fi


	ac_fn_c_check_func "$LINENO" "XScreenSaverQueryInfo" "ac_cv_func_XScreenSaverQueryInfo"
if test "x$ac_cv_func_XScreenSaverQueryInfo" = xyes; then :
if test "x$ac_cv_func_XScreenSaverQueryInfo" = xyes
then :

else
else $as_nop

	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XScreenSaverQueryInfo in -lXext" >&5
$as_echo_n "checking for XScreenSaverQueryInfo in -lXext... " >&6; }
if ${ac_cv_lib_Xext_XScreenSaverQueryInfo+:} false; then :
  $as_echo_n "(cached) " >&6
else
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for XScreenSaverQueryInfo in -lXext" >&5
printf %s "checking for XScreenSaverQueryInfo in -lXext... " >&6; }
if test ${ac_cv_lib_Xext_XScreenSaverQueryInfo+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  ac_check_lib_save_LIBS=$LIBS
LIBS="-lXext  $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

/* Override any GCC internal prototype to avoid an error.
   Use char because int might match the return type of a GCC
   builtin and then its argument prototype would still apply.  */
#ifdef __cplusplus
extern "C"
#endif
char XScreenSaverQueryInfo ();
int
main ()
main (void)
{
return XScreenSaverQueryInfo ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_lib_Xext_XScreenSaverQueryInfo=yes
else
else $as_nop
  ac_cv_lib_Xext_XScreenSaverQueryInfo=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xext_XScreenSaverQueryInfo" >&5
$as_echo "$ac_cv_lib_Xext_XScreenSaverQueryInfo" >&6; }
if test "x$ac_cv_lib_Xext_XScreenSaverQueryInfo" = xyes; then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xext_XScreenSaverQueryInfo" >&5
printf "%s\n" "$ac_cv_lib_Xext_XScreenSaverQueryInfo" >&6; }
if test "x$ac_cv_lib_Xext_XScreenSaverQueryInfo" = xyes
then :

		XLIBSW="$XLIBSW -lXext"
		xss_lib_found=yes

else
else $as_nop

		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for XScreenSaverQueryInfo in -lXss" >&5
$as_echo_n "checking for XScreenSaverQueryInfo in -lXss... " >&6; }
if ${ac_cv_lib_Xss_XScreenSaverQueryInfo+:} false; then :
  $as_echo_n "(cached) " >&6
else
		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for XScreenSaverQueryInfo in -lXss" >&5
printf %s "checking for XScreenSaverQueryInfo in -lXss... " >&6; }
if test ${ac_cv_lib_Xss_XScreenSaverQueryInfo+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  ac_check_lib_save_LIBS=$LIBS
LIBS="-lXss -lXext $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

/* Override any GCC internal prototype to avoid an error.
   Use char because int might match the return type of a GCC
   builtin and then its argument prototype would still apply.  */
#ifdef __cplusplus
extern "C"
#endif
char XScreenSaverQueryInfo ();
int
main ()
main (void)
{
return XScreenSaverQueryInfo ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_lib_Xss_XScreenSaverQueryInfo=yes
else
else $as_nop
  ac_cv_lib_Xss_XScreenSaverQueryInfo=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xss_XScreenSaverQueryInfo" >&5
$as_echo "$ac_cv_lib_Xss_XScreenSaverQueryInfo" >&6; }
if test "x$ac_cv_lib_Xss_XScreenSaverQueryInfo" = xyes; then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xss_XScreenSaverQueryInfo" >&5
printf "%s\n" "$ac_cv_lib_Xss_XScreenSaverQueryInfo" >&6; }
if test "x$ac_cv_lib_Xss_XScreenSaverQueryInfo" = xyes
then :

		    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"
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
8454
8455
8456
8457
8458
8459
8460

8461
8462
8463
8464
8465
8466
8467
8468
8469
8470
8471
8472





8473
8474
8475
8476
8477
8478
8479
8480
8481
8482

8483
8484
8485
8486
8487
8488
8489
8490
8491
8492

8493
8494
8495

8496
8497
8498

8499
8500




8501
8502
8503
8504
8505
8506
8507
8508
8509
8510
8511







-
+











-
-
-
-
-
+
+
+
+
+
+




-
+









-
+
+

-
+


-
+

-
-
-
-
+
+
+
+









fi

    fi
    if test $enable_xss = yes -a $xss_lib_found = yes -a $xss_header_found = yes; then

$as_echo "#define HAVE_XSS 1" >>confdefs.h
printf "%s\n" "#define HAVE_XSS 1" >>confdefs.h

    fi
    CFLAGS=$tk_oldCFlags
    LIBS=$tk_oldLibs
fi

#--------------------------------------------------------------------
#	Figure out whether "char" is unsigned.  If so, set a
#	#define for __CHAR_UNSIGNED__.
#--------------------------------------------------------------------

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether char is unsigned" >&5
$as_echo_n "checking whether char is unsigned... " >&6; }
if ${ac_cv_c_char_unsigned+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether char is unsigned" >&5
printf %s "checking whether char is unsigned... " >&6; }
if test ${ac_cv_c_char_unsigned+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$ac_includes_default
int
main ()
main (void)
{
static int test_array [1 - 2 * !(((char) -1) < 0)];
test_array [0] = 0;
return test_array [0];

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_c_char_unsigned=no
else
else $as_nop
  ac_cv_c_char_unsigned=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_char_unsigned" >&5
$as_echo "$ac_cv_c_char_unsigned" >&6; }
if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then
  $as_echo "#define __CHAR_UNSIGNED__ 1" >>confdefs.h
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_char_unsigned" >&5
printf "%s\n" "$ac_cv_c_char_unsigned" >&6; }
if test $ac_cv_c_char_unsigned = yes; then
  printf "%s\n" "#define __CHAR_UNSIGNED__ 1" >>confdefs.h

fi


#--------------------------------------------------------------------
#	The statements below define a collection of symbols related to
#	building libtk as a shared library instead of a static library.
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
8536
8537
8538
8539
8540
8541
8542


8543
8544
8545

8546
8547
8548

8549
8550
8551
8552
8553
8554


8555
8556
8557
8558
8559


8560
8561
8562
8563
8564
8565


8566
8567
8568
8569
8570


8571
8572
8573


8574
8575
8576
8577
8578
8579
8580
8581
8582
8583
8584
8585
8586
8587
8588
8589
8590

8591
8592
8593
8594
8595
8596
8597
8598

8599
8600
8601
8602
8603
8604
8605
8606







-
-
+
+

-
+
+

-
+





-
-
+
+



-
-
+
+




-
-
+
+



-
-
+
+

-
-
+
+










+
+
+
+

-
+







-
+







# 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

    if test "`uname -s`" = "Darwin" ; then
	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to package libraries" >&5
$as_echo_n "checking how to package libraries... " >&6; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to package libraries" >&5
printf %s "checking how to package libraries... " >&6; }
	# Check whether --enable-framework was given.
if test "${enable_framework+set}" = set; then :
if test ${enable_framework+y}
then :
  enableval=$enable_framework; enable_framework=$enableval
else
else $as_nop
  enable_framework=no
fi

	if test $enable_framework = yes; then
	    if test $SHARED_BUILD = 0; then
		{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Frameworks can only be built if --enable-shared is yes" >&5
$as_echo "$as_me: WARNING: Frameworks can only be built if --enable-shared is yes" >&2;}
		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Frameworks can only be built if --enable-shared is yes" >&5
printf "%s\n" "$as_me: WARNING: Frameworks can only be built if --enable-shared is yes" >&2;}
		enable_framework=no
	    fi
	    if test $tcl_corefoundation = no; then
		{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Frameworks can only be used when CoreFoundation is available" >&5
$as_echo "$as_me: WARNING: Frameworks can only be used when CoreFoundation is available" >&2;}
		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Frameworks can only be used when CoreFoundation is available" >&5
printf "%s\n" "$as_me: WARNING: Frameworks can only be used when CoreFoundation is available" >&2;}
		enable_framework=no
	    fi
	fi
	if test $enable_framework = yes; then
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: framework" >&5
$as_echo "framework" >&6; }
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: framework" >&5
printf "%s\n" "framework" >&6; }
	    FRAMEWORK_BUILD=1
	else
	    if test $SHARED_BUILD = 1; then
		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: shared library" >&5
$as_echo "shared library" >&6; }
		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: shared library" >&5
printf "%s\n" "shared library" >&6; }
	    else
		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: static library" >&5
$as_echo "static library" >&6; }
		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: static library" >&5
printf "%s\n" "static library" >&6; }
	    fi
	    FRAMEWORK_BUILD=0
	fi
    fi

    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="$ac_config_files Tk-Info.plist:../macosx/Tk-Info.plist.in Wish-Info.plist:../macosx/Wish-Info.plist.in"
    ac_config_files="$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

$as_echo "#define TK_FRAMEWORK 1" >>confdefs.h
printf "%s\n" "#define TK_FRAMEWORK 1" >>confdefs.h

    # Construct a fake local framework structure to make linking with
    # '-framework Tk' and running of tktest work
    ac_config_commands="$ac_config_commands Tk.framework"

    LD_LIBRARY_PATH_VAR="DYLD_FRAMEWORK_PATH"
    if test "${libdir}" = '${exec_prefix}/lib'; then
8115
8116
8117
8118
8119
8120
8121

8122
8123
8124
8125
8126
8127
8128
8129
8130

8131
8132
8133
8134
8135
8136
8137
8618
8619
8620
8621
8622
8623
8624
8625
8626
8627
8628
8629
8630
8631
8632
8633
8634
8635
8636
8637
8638
8639
8640
8641
8642







+









+







    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)\"'
8178
8179
8180
8181
8182
8183
8184
8185


8186
8187
8188
8189
8190
8191
8192
8683
8684
8685
8686
8687
8688
8689

8690
8691
8692
8693
8694
8695
8696
8697
8698







-
+
+







# Install time header dir can be set via --includedir
eval "TK_INCLUDE_SPEC=\"-I${includedir}\""

#------------------------------------------------------------------------
# Demo dir
#------------------------------------------------------------------------

if test x"${DEMO_DIR}" = x; then :
if test x"${DEMO_DIR}" = x
then :
  DEMO_DIR='$(TK_LIBRARY)/demos'
fi
eval "TK_DEMO_DIR=\"`echo ${DEMO_DIR} | tr '()' '{}'`\""
eval "TK_DEMO_DIR=\"`echo ${TK_DEMO_DIR} | tr '()' '{}'`\""



8272
8273
8274
8275
8276
8277
8278
8279
8280


8281
8282
8283
8284
8285
8286
8287
8778
8779
8780
8781
8782
8783
8784


8785
8786
8787
8788
8789
8790
8791
8792
8793







-
-
+
+







# 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;} ;;
      *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
printf "%s\n" "$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
8303
8304
8305
8306
8307
8308
8309
8310

8311
8312
8313
8314
8315
8316
8317
8318


8319
8320
8321
8322
8323
8324
8325
8326
8327
8328
8329
8330
8331
8332
8333


8334
8335
8336
8337
8338
8339
8340
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







-
+






-
-
+
+













-
-
+
+







    esac |
    sort
) |
  sed '
     /^ac_cv_env_/b end
     t clear
     :clear
     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
     s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/
     t end
     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
     :end' >>confcache
if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
  if test -w "$cache_file"; then
    if test "x$cache_file" != "x/dev/null"; then
      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
$as_echo "$as_me: updating cache $cache_file" >&6;}
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
printf "%s\n" "$as_me: updating cache $cache_file" >&6;}
      if test ! -f "$cache_file" || test -h "$cache_file"; then
	cat confcache >"$cache_file"
      else
        case $cache_file in #(
        */* | ?:*)
	  mv -f confcache "$cache_file"$$ &&
	  mv -f "$cache_file"$$ "$cache_file" ;; #(
        *)
	  mv -f confcache "$cache_file" ;;
	esac
      fi
    fi
  else
    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;}
  fi
fi
rm -f confcache

test "x$prefix" = xNONE && prefix=$ac_default_prefix
# Let make expand exec_prefix.
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
8379
8380
8381
8382
8383
8384
8385
8386

8387
8388
8389
8390
8391
8392
8393
8394
8395
8396
8397
8398
8399
8400
8401
8402
8403
8404
8405


8406
8407
8408
8409
8410
8411
8412
8885
8886
8887
8888
8889
8890
8891

8892
8893
8894
8895
8896
8897
8898
8899
8900
8901
8902
8903
8904
8905
8906
8907
8908
8909


8910
8911
8912
8913
8914
8915
8916
8917
8918







-
+

















-
-
+
+








ac_libobjs=
ac_ltlibobjs=
U=
for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
  # 1. Remove the extension, and $U if already installed.
  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
  ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"`
  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
  #    will be set to the directory where LIBOBJS objects are built.
  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
done
LIBOBJS=$ac_libobjs

LTLIBOBJS=$ac_ltlibobjs


CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""


: "${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;}
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;}
as_write_fail=0
cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
#! $SHELL
# Generated by $as_me.
# Run this file to recreate the current configuration.
# Compiler output produced by configure, useful for debugging
# configure, is in config.log if it exists.
8421
8422
8423
8424
8425
8426
8427

8428


8429
8430
8431
8432
8433
8434
8435

8436
8437
8438
8439
8440
8441
8442
8443
8444








8445
8446
8447
8448
8449
8450
8451
8452
8453
8454
8455
8456
8457


8458
8459
8460


8461
8462
8463
8464
8465
8466
8467

8468
8469
8470
8471
8472
8473
8474
8475
8476




8477
8478
8479
8480
8481

















8482
8483
8484

8485
8486
8487
8488
8489
8490
8491
8492
8493
8494
8495
8496
8497
8498
8499
8500
8501
8502
8503
8504
8505
8506
8507

8508
8509





8510
8511
8512
8513
8514
8515
8516
8517
8518
8519
8520
8521

8522
8523
8524
8525
8526
8527
8528
8529
8530
8531
8532
8533
8534
8535
8536
8537
8538
8539
8540
8541
8542
8543
8544
8545
8546
8547
8548
8549
8550
8551
8552
8553
8554
8555
8556
8557

8558
8559

8560
8561

8562
8563
8564
8565
8566
8567
8568
8927
8928
8929
8930
8931
8932
8933
8934

8935
8936
8937
8938
8939
8940
8941
8942

8943
8944
8945
8946
8947
8948
8949
8950
8951
8952
8953
8954
8955
8956
8957
8958
8959
8960
8961
8962
8963










8964
8965



8966
8967







8968









8969
8970
8971
8972





8973
8974
8975
8976
8977
8978
8979
8980
8981
8982
8983
8984
8985
8986
8987
8988
8989
8990
8991

8992
8993
8994
8995
8996
8997
8998
8999
9000







9001
9002
9003
9004
9005
9006
9007
9008
9009


9010
9011
9012
9013
9014
9015
9016
9017
9018
9019
9020
9021
9022
9023
9024
9025

9026
9027
9028
9029




















9030
9031
9032
9033
9034
9035
9036
9037
9038
9039
9040
9041

9042
9043

9044
9045
9046
9047
9048
9049
9050
9051
9052
9053
9054







+
-
+
+






-
+









+
+
+
+
+
+
+
+



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


-
+








-
-
-
-
-
-
-








+
-
-
+
+
+
+
+











-
+



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












-
+

-
+


+







cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##

# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
as_nop=:
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
if test ${ZSH_VERSION+y} && (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
else $as_nop
  case `(set -o) 2>/dev/null` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;
esac
fi



# Reset variables that may have inherited troublesome values from
# the environment.

# IFS needs to be set, to space, tab, and newline, in precisely that order.
# (If _AS_PATH_WALK were called with IFS unset, it would have the
# side effect of setting IFS to empty, thus disabling word splitting.)
# Quoting is to prevent editors from complaining about space-tab.
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 --'
IFS=" ""	$as_nl"

elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
  as_echo='printf %s\n'
  as_echo_n='printf %s'
PS1='$ '
PS2='> '
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
PS4='+ '
      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

# Ensure predictable behavior from utilities with locale-dependent output.
LC_ALL=C
export LC_ALL
    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
LANGUAGE=C
export LANGUAGE

# We cannot yet rely on "unset" to work, but we need these variables
# to be unset--not just set to an empty or harmless value--now, to
# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh).  This construct
# also avoids known problems related to "unset" and subshell syntax
# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
do eval test \${$as_var+y} \
  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
done

# Ensure that fds 0, 1, and 2 are open.
if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
if (exec 3>&2)            ; then :; else exec 2>/dev/null; fi

# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
if ${PATH_SEPARATOR+false} :; then
  PATH_SEPARATOR=:
  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
      PATH_SEPARATOR=';'
  }
fi


# IFS
# We need space, tab and new line, in precisely that order.  Quoting is
# there to prevent editors from complaining about space-tab.
# (If _AS_PATH_WALK were called with IFS unset, it would disable word
# splitting by setting IFS to empty value.)
IFS=" ""	$as_nl"

# Find who we are.  Look in the path if we contain no directory separator.
as_myself=
case $0 in #((
  *[\\/]* ) as_myself=$0 ;;
  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    test -r "$as_dir$0" && as_myself=$as_dir$0 && break
  done
IFS=$as_save_IFS

     ;;
esac
# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
  as_myself=$0
fi
if test ! -f "$as_myself"; then
  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
  exit 1
fi

# Unset variables that we do not need and which cause bugs (e.g. in
# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
# suppresses any "Segmentation fault" message there.  '((' could
# trigger a bug in pdksh 5.2.14.
for as_var in BASH_ENV ENV MAIL MAILPATH
do eval test x\${$as_var+set} = xset \
  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
done
PS1='$ '
PS2='> '
PS4='+ '

# NLS nuisances.
LC_ALL=C
export LC_ALL
LANGUAGE=C
export LANGUAGE

# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH


# as_fn_error STATUS ERROR [LINENO LOG_FD]
# ----------------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
# script with STATUS, using 1 if that was 0.
as_fn_error ()
{
  as_status=$1; test $as_status -eq 0 && as_status=1
  if test "$4"; then
    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
  fi
  $as_echo "$as_me: error: $2" >&2
  printf "%s\n" "$as_me: error: $2" >&2
  as_fn_exit $as_status
} # as_fn_error



# as_fn_set_status STATUS
# -----------------------
# Set $? to STATUS, without forking.
as_fn_set_status ()
{
8583
8584
8585
8586
8587
8588
8589

8590
8591
8592
8593
8594
8595
8596


8597
8598
8599
8600
8601

8602
8603
8604
8605
8606
8607
8608
8609
8610
8611
8612
8613


8614
8615
8616
8617
8618

8619
8620
8621
8622
8623
8624
8625
9069
9070
9071
9072
9073
9074
9075
9076
9077
9078
9079
9080
9081
9082

9083
9084
9085
9086
9087
9088

9089
9090
9091
9092
9093
9094
9095
9096
9097
9098
9099
9100

9101
9102
9103
9104
9105
9106

9107
9108
9109
9110
9111
9112
9113
9114







+






-
+
+




-
+











-
+
+




-
+







# ---------------
# 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 :
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
else $as_nop
  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 :
if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
then :
  eval 'as_fn_arith ()
  {
    as_val=$(( $* ))
  }'
else
else $as_nop
  as_fn_arith ()
  {
    as_val=`expr "$@" || test $? -eq 1`
  }
fi # as_fn_arith


8642
8643
8644
8645
8646
8647
8648
8649

8650
8651
8652
8653
8654
8655
8656
9131
9132
9133
9134
9135
9136
9137

9138
9139
9140
9141
9142
9143
9144
9145







-
+







  as_dirname=false
fi

as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
	 X"$0" : 'X\(//\)$' \| \
	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X/"$0" |
printf "%s\n" X/"$0" |
    sed '/^.*\/\([^/][^/]*\)\/*$/{
	    s//\1/
	    q
	  }
	  /^X\/\(\/\/\)$/{
	    s//\1/
	    q
8664
8665
8666
8667
8668
8669
8670




8671
8672
8673
8674
8675
8676
8677
8678
8679
8680
8681
8682






8683
8684
8685
8686
8687
8688
8689
9153
9154
9155
9156
9157
9158
9159
9160
9161
9162
9163
9164
9165
9166
9167
9168
9169
9170
9171
9172
9173
9174
9175
9176
9177
9178
9179
9180
9181
9182
9183
9184
9185
9186
9187
9188







+
+
+
+












+
+
+
+
+
+







# 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


# Determine whether it's possible to make 'echo' print without a newline.
# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
# for compatibility with existing Makefiles.
ECHO_C= ECHO_N= ECHO_T=
case `echo -n x` in #(((((
-n*)
  case `echo 'xy\c'` in
  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
  xy)  ECHO_C='\c';;
  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
       ECHO_T='	';;
  esac;;
*)
  ECHO_N='-n';;
esac

# For backward compatibility with old third-party macros, we provide
# the shell variables $as_echo and $as_echo_n.  New code should use
# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
as_echo='printf %s\n'
as_echo_n='printf %s'

rm -f conf$$ conf$$.exe conf$$.file
if test -d conf$$.dir; then
  rm -f conf$$.dir/conf$$.file
else
  rm -f conf$$.dir
  mkdir conf$$.dir 2>/dev/null
8718
8719
8720
8721
8722
8723
8724
8725

8726
8727
8728
8729
8730
8731
8732
8733
8734

8735
8736
8737
8738
8739
8740
8741
9217
9218
9219
9220
9221
9222
9223

9224
9225
9226
9227
9228
9229
9230
9231
9232

9233
9234
9235
9236
9237
9238
9239
9240







-
+








-
+







  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=`printf "%s\n" "$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" |
printf "%s\n" X"$as_dir" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q
8790
8791
8792
8793
8794
8795
8796
8797

8798
8799
8800
8801
8802
8803
8804
9289
9290
9291
9292
9293
9294
9295

9296
9297
9298
9299
9300
9301
9302
9303







-
+








cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# Save the log message, to keep $0 and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by tk $as_me 8.7, which was
generated by GNU Autoconf 2.69.  Invocation command line was
generated by GNU Autoconf 2.70.  Invocation command line was

  CONFIG_FILES    = $CONFIG_FILES
  CONFIG_HEADERS  = $CONFIG_HEADERS
  CONFIG_LINKS    = $CONFIG_LINKS
  CONFIG_COMMANDS = $CONFIG_COMMANDS
  $ $0 $@

8843
8844
8845
8846
8847
8848
8849


8850
8851

8852
8853
8854

8855
8856
8857

8858
8859
8860
8861
8862
8863
8864
9342
9343
9344
9345
9346
9347
9348
9349
9350
9351

9352
9353
9354

9355
9356
9357

9358
9359
9360
9361
9362
9363
9364
9365







+
+

-
+


-
+


-
+








Configuration commands:
$config_commands

Report bugs to the package provider."

_ACEOF
ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"`
ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"`
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
tk config.status 8.7
configured by $0, generated by GNU Autoconf 2.69,
configured by $0, generated by GNU Autoconf 2.70,
  with options \\"\$ac_cs_config\\"

Copyright (C) 2012 Free Software Foundation, Inc.
Copyright (C) 2020 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."

ac_pwd='$ac_pwd'
srcdir='$srcdir'
test -n "\$AWK" || AWK=awk
_ACEOF
8887
8888
8889
8890
8891
8892
8893
8894

8895
8896

8897
8898
8899
8900
8901
8902

8903
8904
8905
8906
8907
8908

8909
8910
8911
8912
8913
8914
8915
9388
9389
9390
9391
9392
9393
9394

9395
9396

9397
9398
9399
9400
9401
9402

9403
9404
9405
9406
9407
9408

9409
9410
9411
9412
9413
9414
9415
9416







-
+

-
+





-
+





-
+







  esac

  case $ac_option in
  # Handling of the options.
  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
    ac_cs_recheck=: ;;
  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
    $as_echo "$ac_cs_version"; exit ;;
    printf "%s\n" "$ac_cs_version"; exit ;;
  --config | --confi | --conf | --con | --co | --c )
    $as_echo "$ac_cs_config"; exit ;;
    printf "%s\n" "$ac_cs_config"; exit ;;
  --debug | --debu | --deb | --de | --d | -d )
    debug=: ;;
  --file | --fil | --fi | --f )
    $ac_shift
    case $ac_optarg in
    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
    *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
    '') as_fn_error $? "missing file argument" ;;
    esac
    as_fn_append CONFIG_FILES " '$ac_optarg'"
    ac_need_defaults=false;;
  --he | --h |  --help | --hel | -h )
    $as_echo "$ac_cs_usage"; exit ;;
    printf "%s\n" "$ac_cs_usage"; exit ;;
  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
  | -silent | --silent | --silen | --sile | --sil | --si | --s)
    ac_cs_silent=: ;;

  # This is an error.
  -*) as_fn_error $? "unrecognized option: \`$1'
Try \`$0 --help' for more information." ;;
8929
8930
8931
8932
8933
8934
8935
8936

8937
8938
8939
8940
8941
8942
8943
8944
8945
8946
8947
8948
8949
8950

8951
8952
8953
8954
8955
8956
8957
8958
8959
8960
8961
8962
8963
8964
8965
8966
8967
8968
8969

8970
8971
8972
8973
8974
8975
8976
8977
8978
8979
8980
8981
8982
8983
8984
8985
8986


8987
8988
8989
8990
8991
8992
8993
9430
9431
9432
9433
9434
9435
9436

9437
9438
9439
9440
9441
9442
9443
9444
9445
9446
9447
9448
9449
9450

9451
9452
9453
9454
9455
9456
9457
9458
9459
9460
9461
9462
9463
9464
9465
9466
9467
9468
9469
9470
9471
9472
9473
9474
9475
9476
9477
9478
9479
9480
9481
9482
9483
9484
9485
9486


9487
9488
9489
9490
9491
9492
9493
9494
9495







-
+













-
+



















+















-
-
+
+







fi

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then
  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
  shift
  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
  \printf "%s\n" "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"
  printf "%s\n" "$ac_log"
} >&5

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
#
# INIT-COMMANDS
#
VERSION=${TK_VERSION} && tk_aqua=${tk_aqua}

_ACEOF

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1

# Handling of arguments.
for ac_config_target in $ac_config_targets
do
  case $ac_config_target in
    "Tk-Info.plist") CONFIG_FILES="$CONFIG_FILES Tk-Info.plist:../macosx/Tk-Info.plist.in" ;;
    "Wish-Info.plist") CONFIG_FILES="$CONFIG_FILES Wish-Info.plist:../macosx/Wish-Info.plist.in" ;;
    "Credits.html") CONFIG_FILES="$CONFIG_FILES Credits.html:../macosx/Credits.html.in" ;;
    "Tk.framework") CONFIG_COMMANDS="$CONFIG_COMMANDS Tk.framework" ;;
    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile:../unix/Makefile.in" ;;
    "tkConfig.sh") CONFIG_FILES="$CONFIG_FILES tkConfig.sh:../unix/tkConfig.sh.in" ;;
    "tk.pc") CONFIG_FILES="$CONFIG_FILES tk.pc:../unix/tk.pc.in" ;;

  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
  esac
done


# If the user did not use the arguments to specify the items to instantiate,
# then the envvar interface is used.  Set only those that are not.
# We use the long form for the default assignment because of an extremely
# bizarre bug on SunOS 4.1.3.
if $ac_need_defaults; then
  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
  test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files
  test ${CONFIG_COMMANDS+y} || CONFIG_COMMANDS=$config_commands
fi

# Have a temporary directory for convenience.  Make it in the build tree
# simply because there is no reason against having it here, and in addition,
# creating and moving files from /tmp can sometimes cause problems.
# Hook for its removal unless debugging.
# Note that there is a small window in which the directory will not be cleaned:
9207
9208
9209
9210
9211
9212
9213
9214

9215
9216
9217
9218
9219
9220
9221
9222

9223
9224
9225
9226
9227


9228
9229
9230
9231
9232

9233
9234
9235
9236
9237
9238
9239
9240
9241
9242
9243
9244
9245
9246
9247
9248
9249

9250
9251
9252
9253
9254
9255
9256
9709
9710
9711
9712
9713
9714
9715

9716
9717
9718
9719
9720
9721
9722
9723

9724
9725
9726
9727


9728
9729
9730
9731
9732
9733

9734
9735
9736
9737
9738
9739
9740
9741
9742
9743
9744
9745
9746
9747
9748
9749
9750

9751
9752
9753
9754
9755
9756
9757
9758







-
+







-
+



-
-
+
+




-
+
















-
+







	 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
      case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
      as_fn_append ac_file_inputs " '$ac_f'"
    done

    # Let's still pretend it is `configure' which instantiates (i.e., don't
    # use $as_me), people would be surprised to read:
    #    /* config.h.  Generated by config.status.  */
    configure_input='Generated from '`
	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
	  printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
	`' by configure.'
    if test x"$ac_file" != x-; then
      configure_input="$ac_file.  $configure_input"
      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
$as_echo "$as_me: creating $ac_file" >&6;}
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
printf "%s\n" "$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" |
       ac_sed_conf_input=`printf "%s\n" "$configure_input" |
       sed 's/[\\\\&|]/\\\\&/g'`;; #(
    *) ac_sed_conf_input=$configure_input;;
    esac

    case $ac_tag in
    *:-:* | *:-) cat >"$ac_tmp/stdin" \
      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
    esac
    ;;
  esac

  ac_dir=`$as_dirname -- "$ac_file" ||
$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	 X"$ac_file" : 'X\(//\)[^/]' \| \
	 X"$ac_file" : 'X\(//\)$' \| \
	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$ac_file" |
printf "%s\n" X"$ac_file" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q
9266
9267
9268
9269
9270
9271
9272
9273

9274
9275

9276
9277
9278
9279
9280
9281
9282
9768
9769
9770
9771
9772
9773
9774

9775
9776

9777
9778
9779
9780
9781
9782
9783
9784







-
+

-
+







	  s/.*/./; q'`
  as_dir="$ac_dir"; as_fn_mkdir_p
  ac_builddir=.

case "$ac_dir" in
.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
*)
  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
  ac_dir_suffix=/`printf "%s\n" "$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_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
  case $ac_top_builddir_sub in
  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
  esac ;;
esac
ac_abs_top_builddir=$ac_pwd
ac_abs_builddir=$ac_pwd$ac_dir_suffix
9321
9322
9323
9324
9325
9326
9327
9328
9329


9330
9331
9332
9333
9334
9335
9336
9823
9824
9825
9826
9827
9828
9829


9830
9831
9832
9833
9834
9835
9836
9837
9838







-
-
+
+







/@docdir@/p
/@infodir@/p
/@localedir@/p
/@mandir@/p'
case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
*datarootdir*) ac_datarootdir_seen=yes;;
*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
  ac_datarootdir_hack='
  s&@datadir@&$datadir&g
  s&@docdir@&$docdir&g
  s&@infodir@&$infodir&g
  s&@localedir@&$localedir&g
9364
9365
9366
9367
9368
9369
9370
9371

9372
9373

9374
9375
9376
9377
9378
9379
9380
9381
9382
9383
9384
9385
9386


9387
9388
9389
9390
9391
9392
9393
9866
9867
9868
9869
9870
9871
9872

9873
9874

9875
9876
9877
9878
9879
9880
9881
9882
9883
9884
9885
9886


9887
9888
9889
9890
9891
9892
9893
9894
9895







-
+

-
+











-
-
+
+







eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5

test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
      "$ac_tmp/out"`; test -z "$ac_out"; } &&
  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
  { printf "%s\n" "$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'
printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined.  Please make sure it is defined" >&2;}

  rm -f "$ac_tmp/stdin"
  case $ac_file in
  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
  esac \
  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
 ;;


  :C)  { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
$as_echo "$as_me: executing $ac_file commands" >&6;}
  :C)  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
printf "%s\n" "$as_me: executing $ac_file commands" >&6;}
 ;;
  esac


  case $ac_file$ac_mode in
    "Tk.framework":C) n=Tk &&
        f=$n.framework && v=Versions/$VERSION &&
9427
9428
9429
9430
9431
9432
9433
9434
9435


9436
9437
9438

9929
9930
9931
9932
9933
9934
9935


9936
9937
9938
9939
9940
9941







-
-
+
+



+
  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
  exec 5>>config.log
  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
  # would make configure fail if this is the last instruction.
  $ac_cs_success || as_fn_exit 1
fi
if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
fi



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

1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19


20
21
22
23
24
25
26
27
28
29
-
+





-
+












-
-
+
+
+







#! /bin/bash -norc
! /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)
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
    /* override */ #undef PACKAGE_TARNAME
    /* override */ #undef PACKAGE_VERSION
    /* override */ #undef PACKAGE_STRING
    #endif /* _TKCONFIG */])
])

TK_VERSION=8.7
TK_MAJOR_VERSION=8
TK_MINOR_VERSION=7
TK_PATCH_LEVEL="a4"
88
89
90
91
92
93
94
95

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

96
97
98
99
100
101
102
103







-
+







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

#------------------------------------------------------------------------
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156
157
158
159
160
161
162

163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182

183
184
185
186
187
188
189
190
191
192
193
194
195

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

211
212
213
214
215
216
217
218
219
220
221
222
223
224
225

226
227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
242
243
244
245
246
247

248
249
250
251
252
253
254
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156
157
158
159
160
161
162

163

164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181

182

183
184
185
186
187
188
189
190
191

192

193















194















195
196
197
198
199
200
201



202
203
204
205
206
207
208
209
210
211
212
213


214
215
216
217
218
219
220
221







-
+













-
+
-


















-
+
-









-

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






-
-
-
+











-
-
+







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.])
        [[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;],
    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])])
	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_CHECK_HEADERS_ONCE([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_CHECK_TYPES([intptr_t, uintptr_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], [
#include <stdint.h>
    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; pwd.pw_gecos;],
	    tcl_cv_pwd_pw_gecos=yes, tcl_cv_pwd_pw_gecos=no)])
    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,
	AC_HELP_STRING([--enable-aqua=yes|no],
	    [use Aqua windowingsystem on Mac OS X (default: no)]),
	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
266
267
268
269
270
271
272
273
274

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

295
296
297
298
299
300
301

302
303
304
305
306
307
308
309
310
311

312
313
314
315
316
317
318
319

320
321
322
323
324
325
326
327
328
329

330
331
332
333
334
335
336
337
338
339
340
341
342




343
344
345
346
347
348
349
233
234
235
236
237
238
239


240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258


259
260
261
262
263
264
265

266
267
268
269
270
271
272
273
274


275
276
277
278
279
280
281
282

283
284
285
286
287
288
289
290
291
292

293
294
295
296
297
298
299
300
301
302
303
304
305

306
307
308
309
310
311
312
313
314
315
316







-
-
+


















-
-
+






-
+








-
-
+







-
+









-
+












-
+
+
+
+







	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)
		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_TRY_LINK([#include <math.h>], [double f = sin(1.0);],
		tcl_cv_ld_weak_l=yes, tcl_cv_ld_weak_l=no)
	    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_TRY_LINK([
	    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)
		]], [[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([
	    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)
		]], [[]])],[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"
    LIBS="$LIBS -framework Cocoa -framework Carbon -framework IOKit -framework Security"
    if test -d /System/Library/Frameworks/UserNotifications.framework; then
        LIBS="$LIBS -framework UserNotifications"
    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
    #--------------------------------------------------------------------
417
418
419
420
421
422
423
424

425
426

427
428

429
430
431
432

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

446
447
448
449
450
451
452
384
385
386
387
388
389
390

391
392

393
394

395
396
397
398

399
400
401
402
403
404
405
406
407
408
409
410


411
412
413
414
415
416
417
418







-
+

-
+

-
+



-
+











-
-
+








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([
    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]))
    ],[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)]),
	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"
533
534
535
536
537
538
539
540
541

542
543
544
545
546
547
548
499
500
501
502
503
504
505


506
507
508
509
510
511
512
513







-
-
+







    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)]),
	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
613
614
615
616
617
618
619




620
621

622
623
624
625
626
627
628
578
579
580
581
582
583
584
585
586
587
588
589

590
591
592
593
594
595
596
597







+
+
+
+

-
+







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])
    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
651
652
653
654
655
656
657

658
659
660
661
662
663
664
665
666

667
668
669
670
671
672
673
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644







+









+







    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)\"'

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=2011-04-20.01; # UTC
scriptversion=2020-07-26.22; # UTC

# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
31
32
33
34
35
36
37
38

39
40
41
42
43

44
45
46

47
48

49
50
51
52
53

54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85




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

101
102
103
104
105
106
107
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46

47
48

49
50

51


52



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











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

89
90
91
92
93
94
95
96







-
+





+


-
+

-
+

-

-
-
+
-
-
-














-
-
-
-
-
-
-
-
-
-
-




+
+
+
+














-
+







# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.

tab='	'
nl='
'
IFS=" ""	$nl"
IFS=" $tab$nl"

# set DOITPROG to echo to test this script
# Set DOITPROG to "echo" to test this script.

# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
  doit_exec=exec
doit_exec=${doit:-exec}
else
  doit_exec=$doit
fi

# Put in absolute file names if you don't have them in your path;
# or use environment vars.

chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}

posix_glob='?'
initialize_posix_glob='
  test "$posix_glob" != "?" || {
    if (set -f) 2>/dev/null; then
      posix_glob=
    else
      posix_glob=:
    fi
  }
'

posix_mkdir=

# Desired mode of installed file.
mode=0755

# Create dirs (including intermediate dirs) using mode 755.
# This is like GNU 'install' as of coreutils 8.32 (2020).
mkdir_umask=22

chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=

src=
dst=
dir_arg=
dst_arg=

copy_on_change=false
no_target_directory=
is_target_a_directory=possibly

usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
   or: $0 [OPTION]... SRCFILES... DIRECTORY
   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
   or: $0 [OPTION]... -d DIRECTORIES...

116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

142
143
144
145
146

147
148
149
150
151
152





153
154
155

156
157
158
159
160

161


162
163






164
165

166
167
168
169
170


171
172
173


174
175
176
177
178










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




193
194
195
196
197
198
199
200
201

202
203
204









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

223
224

225
226
227
228
229

230
231

232
233
234
235
236
237
238
239

240
241

242
243
244
245
246
247
248
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

130
131
132
133
134

135






136
137
138
139
140
141
142

143
144
145
146
147

148
149
150
151


152
153
154
155
156
157
158

159
160
161
162


163
164
165


166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208

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

239
240

241
242
243
244
245

246
247

248
249
250
251
252
253
254
255

256
257

258
259
260
261
262
263
264
265







-
+

















-
+




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


-
+




-
+

+
+
-
-
+
+
+
+
+
+

-
+



-
-
+
+

-
-
+
+





+
+
+
+
+
+
+
+
+
+














+
+
+
+








-
+



+
+
+
+
+
+
+
+
+

















-
+

-
+




-
+

-
+







-
+

-
+







  -c            (ignored)
  -C            install only if different (preserve the last data modification time)
  -d            create directories instead of installing files.
  -g GROUP      $chgrpprog installed files to GROUP.
  -m MODE       $chmodprog installed files to MODE.
  -o USER       $chownprog installed files to USER.
  -s            $stripprog installed files.
  -S            $stripprog installed files.
  -S OPTION     $stripprog installed files using OPTION.
  -t DIRECTORY  install into DIRECTORY.
  -T            report an error if DSTFILE is a directory.

Environment variables override the default commands:
  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
  RMPROG STRIPPROG
"

while test $# -ne 0; do
  case $1 in
    -c) ;;

    -C) copy_on_change=true;;

    -d) dir_arg=true;;

    -g) chgrpcmd="$chgrpprog $2"
	shift;;
        shift;;

    --help) echo "$usage"; exit $?;;

    -m) mode=$2
	case $mode in
        case $mode in
	  *' '* | *'	'* | *'
'*	  | *'*'* | *'?'* | *'['*)
	    echo "$0: invalid mode: $mode" >&2
	    exit 1;;
	esac
	shift;;
          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
            echo "$0: invalid mode: $mode" >&2
            exit 1;;
        esac
        shift;;

    -o) chowncmd="$chownprog $2"
	shift;;
        shift;;

    -s) stripcmd=$stripprog;;

    -S) stripcmd="$stripprog $2"
	shift;;
        shift;;

    -t)
        is_target_a_directory=always
    -t) dst_arg=$2
	shift;;
        dst_arg=$2
        # Protect names problematic for 'test' and other utilities.
        case $dst_arg in
          -* | [=\(\)!]) dst_arg=./$dst_arg;;
        esac
        shift;;

    -T) no_target_directory=true;;
    -T) is_target_a_directory=never;;

    --version) echo "$0 $scriptversion"; exit $?;;

    --)	shift
	break;;
    --) shift
        break;;

    -*)	echo "$0: invalid option: $1" >&2
	exit 1;;
    -*) echo "$0: invalid option: $1" >&2
        exit 1;;

    *)  break;;
  esac
  shift
done

# We allow the use of options -d and -T together, by making -d
# take the precedence; this is for compatibility with GNU install.

if test -n "$dir_arg"; then
  if test -n "$dst_arg"; then
    echo "$0: target directory not allowed when installing a directory." >&2
    exit 1
  fi
fi

if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
  # When -d is used, all remaining arguments are directories to create.
  # When -t is used, the destination is already specified.
  # Otherwise, the last argument is the destination.  Remove it from $@.
  for arg
  do
    if test -n "$dst_arg"; then
      # $@ is not empty: it contains at least $arg.
      set fnord "$@" "$dst_arg"
      shift # fnord
    fi
    shift # arg
    dst_arg=$arg
    # Protect names problematic for 'test' and other utilities.
    case $dst_arg in
      -* | [=\(\)!]) dst_arg=./$dst_arg;;
    esac
  done
fi

if test $# -eq 0; then
  if test -z "$dir_arg"; then
    echo "$0: no input file specified." >&2
    exit 1
  fi
  # It's OK to call `install-sh -d' without argument.
  # It's OK to call 'install-sh -d' without argument.
  # This can happen when creating conditional directories.
  exit 0
fi

if test -z "$dir_arg"; then
  if test $# -gt 1 || test "$is_target_a_directory" = always; then
    if test ! -d "$dst_arg"; then
      echo "$0: $dst_arg: Is not a directory." >&2
      exit 1
    fi
  fi
fi

if test -z "$dir_arg"; then
  do_exit='(exit $ret); exit $ret'
  trap "ret=129; $do_exit" 1
  trap "ret=130; $do_exit" 2
  trap "ret=141; $do_exit" 13
  trap "ret=143; $do_exit" 15

  # Set umask so as not to create temps with too-generous modes.
  # However, 'strip' requires both read and write access to temps.
  case $mode in
    # Optimize common cases.
    *644) cp_umask=133;;
    *755) cp_umask=22;;

    *[0-7])
      if test -z "$stripcmd"; then
	u_plus_rw=
        u_plus_rw=
      else
	u_plus_rw='% 200'
        u_plus_rw='% 200'
      fi
      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
    *)
      if test -z "$stripcmd"; then
	u_plus_rw=
        u_plus_rw=
      else
	u_plus_rw=,u+rw
        u_plus_rw=,u+rw
      fi
      cp_umask=$mode$u_plus_rw;;
  esac
fi

for src
do
  # Protect names starting with `-'.
  # Protect names problematic for 'test' and other utilities.
  case $src in
    -*) src=./$src;;
    -* | [=\(\)!]) src=./$src;;
  esac

  if test -n "$dir_arg"; then
    dst=$src
    dstdir=$dst
    test -d "$dstdir"
    dstdir_status=$?
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270

271
272
273
274
275



276
277
278





279
280
281
282

283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311





312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340







341
342
343


344
345
346
347
348
349
350








351




352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378





























379
380
381
382
383
384
385


386
387
388
389
390

391
392
393
394
395
396
397



398
399
400
401
402
403
404

405
406
407

408
409
410
411
412
413
414

415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433


















434
435
436
437
438
439
440
441





442
443
444
445
446
447
448
449
450
451
452
453
454
455


456
457
458
459
460











461

462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477


478
479
480

481
482
483

484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511















512
513
514


515
516
517
518
519
520
521
522
523

524
525
526

527
528
273
274
275
276
277
278
279

280




281

282

283



284
285
286
287
288

289
290
291
292
293
294
295


296

























297
298
299
300
301
302
303
304
305
306
307
308
309
310
311























312
313
314
315
316
317
318
319


320
321







322
323
324
325
326
327
328
329
330
331
332
333
334



























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

364
365
366
367


368
369
370
371
372
373

374
375
376
377
378



379
380
381
382
383


384
385

386
387
388

389
390
391
392
393
394
395

396
397


















398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418





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


436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453

454
455
456
457
458
459
460
461
462
463
464
465
466
467
468


469
470



471
472
473

474

475
476
477
478
479
480
481
482
483
484
485
486















487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502


503
504
505
506
507
508
509
510
511
512

513
514
515

516
517
518







-

-
-
-
-

-
+
-

-
-
-
+
+
+


-
+
+
+
+
+


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




+
+
+
+
+






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

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

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




-
-
+
+




-
+




-
-
-
+
+
+


-
-


-
+


-
+






-
+

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



-
-
-
-
-
+
+
+
+
+












-
-
+
+





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














-
-
+
+
-
-
-
+


-
+
-












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

-
-
+
+








-
+


-
+


      exit 1
    fi

    if test -z "$dst_arg"; then
      echo "$0: no destination specified." >&2
      exit 1
    fi

    dst=$dst_arg
    # Protect names starting with `-'.
    case $dst in
      -*) dst=./$dst;;
    esac

    # If destination is a directory, append the input filename; won't work
    # If destination is a directory, append the input filename.
    # if double slashes aren't ignored.
    if test -d "$dst"; then
      if test -n "$no_target_directory"; then
	echo "$0: $dst_arg: Is a directory" >&2
	exit 1
      if test "$is_target_a_directory" = never; then
        echo "$0: $dst_arg: Is a directory" >&2
        exit 1
      fi
      dstdir=$dst
      dst=$dstdir/`basename "$src"`
      dstbase=`basename "$src"`
      case $dst in
	*/) dst=$dst$dstbase;;
	*)  dst=$dst/$dstbase;;
      esac
      dstdir_status=0
    else
      # Prefer dirname, but fall back on a substitute if dirname fails.
      dstdir=`
      dstdir=`dirname "$dst"`
	(dirname "$dst") 2>/dev/null ||
	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	     X"$dst" : 'X\(//\)[^/]' \| \
	     X"$dst" : 'X\(//\)$' \| \
	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
	echo X"$dst" |
	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
		   s//\1/
		   q
		 }
		 /^X\(\/\/\)[^/].*/{
		   s//\1/
		   q
		 }
		 /^X\(\/\/\)$/{
		   s//\1/
		   q
		 }
		 /^X\(\/\).*/{
		   s//\1/
		   q
		 }
		 s/.*/./; q'
      `

      test -d "$dstdir"
      dstdir_status=$?
    fi
  fi

  case $dstdir in
    */) dstdirslash=$dstdir;;
    *)  dstdirslash=$dstdir/;;
  esac

  obsolete_mkdir_used=false

  if test $dstdir_status != 0; then
    case $posix_mkdir in
      '')
	# Create intermediate dirs using mode 755 as modified by the umask.
	# This is like FreeBSD 'install' as of 1997-10-28.
	umask=`umask`
	case $stripcmd.$umask in
	  # Optimize common cases.
	  *[2367][2367]) mkdir_umask=$umask;;
	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;

	  *[0-7])
	    mkdir_umask=`expr $umask + 22 \
	      - $umask % 100 % 40 + $umask % 20 \
	      - $umask % 10 % 4 + $umask % 2
	    `;;
	  *) mkdir_umask=$umask,go-w;;
	esac

	# With -d, create the new directory with the user-specified mode.
	# Otherwise, rely on $mkdir_umask.
	if test -n "$dir_arg"; then
	  mkdir_mode=-m$mode
	else
	  mkdir_mode=
	fi
        # With -d, create the new directory with the user-specified mode.
        # Otherwise, rely on $mkdir_umask.
        if test -n "$dir_arg"; then
          mkdir_mode=-m$mode
        else
          mkdir_mode=
        fi

	posix_mkdir=false
	case $umask in
        posix_mkdir=false
	# The $RANDOM variable is not portable (e.g., dash).  Use it
	  *[123567][0-7][0-7])
	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
	    ;;
	  *)
	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
	# here however when possible just to lower collision chance.
	tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$

	trap '
	  ret=$?
	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
	  exit $ret
	' 0

	# Because "mkdir -p" follows existing symlinks and we likely work
	# directly in world-writeable /tmp, make sure that the '$tmpdir'
	# directory is successfully created first before we actually test
	# 'mkdir -p'.
	    if (umask $mkdir_umask &&
		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
	    then
	      if test -z "$dir_arg" || {
		   # Check for POSIX incompatibilities with -m.
		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
		   # other-writeable bit of parent directory when it shouldn't.
		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
		   case $ls_ld_tmpdir in
		     d????-?r-*) different_mode=700;;
		     d????-?--*) different_mode=755;;
		     *) false;;
		   esac &&
		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
		   }
		 }
	      then posix_mkdir=:
	      fi
	      rmdir "$tmpdir/d" "$tmpdir"
	    else
	      # Remove any dirs left behind by ancient mkdir implementations.
	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
	    fi
	    trap '' 0;;
	if (umask $mkdir_umask &&
	    $mkdirprog $mkdir_mode "$tmpdir" &&
	    exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
	then
	  if test -z "$dir_arg" || {
	       # Check for POSIX incompatibilities with -m.
	       # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
	       # other-writable bit of parent directory when it shouldn't.
	       # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
	       test_tmpdir="$tmpdir/a"
	       ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
	       case $ls_ld_tmpdir in
		 d????-?r-*) different_mode=700;;
		 d????-?--*) different_mode=755;;
		 *) false;;
	       esac &&
	       $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
		 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
		 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
	       }
	     }
	  then posix_mkdir=:
	  fi
	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
	else
	  # Remove any dirs left behind by ancient mkdir implementations.
	  rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
	fi
	trap '' 0;;
	esac;;
    esac

    if
      $posix_mkdir && (
	umask $mkdir_umask &&
	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
        umask $mkdir_umask &&
        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
      )
    then :
    else

      # The umask is ridiculous, or mkdir does not conform to POSIX,
      # mkdir does not conform to POSIX,
      # or it failed possibly due to a race condition.  Create the
      # directory the slow way, step by step, checking for races as we go.

      case $dstdir in
	/*) prefix='/';;
	-*) prefix='./';;
	*)  prefix='';;
        /*) prefix='/';;
        [-=\(\)!]*) prefix='./';;
        *)  prefix='';;
      esac

      eval "$initialize_posix_glob"

      oIFS=$IFS
      IFS=/
      $posix_glob set -f
      set -f
      set fnord $dstdir
      shift
      $posix_glob set +f
      set +f
      IFS=$oIFS

      prefixes=

      for d
      do
	test -z "$d" && continue
        test X"$d" = X && continue

	prefix=$prefix$d
	if test -d "$prefix"; then
	  prefixes=
	else
	  if $posix_mkdir; then
	    (umask=$mkdir_umask &&
	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
	    # Don't fail if two instances are running concurrently.
	    test -d "$prefix" || exit 1
	  else
	    case $prefix in
	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
	      *) qprefix=$prefix;;
	    esac
	    prefixes="$prefixes '$qprefix'"
	  fi
	fi
	prefix=$prefix/
        prefix=$prefix$d
        if test -d "$prefix"; then
          prefixes=
        else
          if $posix_mkdir; then
            (umask $mkdir_umask &&
             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
            # Don't fail if two instances are running concurrently.
            test -d "$prefix" || exit 1
          else
            case $prefix in
              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
              *) qprefix=$prefix;;
            esac
            prefixes="$prefixes '$qprefix'"
          fi
        fi
        prefix=$prefix/
      done

      if test -n "$prefixes"; then
	# Don't fail if two instances are running concurrently.
	(umask $mkdir_umask &&
	 eval "\$doit_exec \$mkdirprog $prefixes") ||
	  test -d "$dstdir" || exit 1
	obsolete_mkdir_used=true
        # Don't fail if two instances are running concurrently.
        (umask $mkdir_umask &&
         eval "\$doit_exec \$mkdirprog $prefixes") ||
          test -d "$dstdir" || exit 1
        obsolete_mkdir_used=true
      fi
    fi
  fi

  if test -n "$dir_arg"; then
    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
  else

    # Make a couple of temp file names in the proper directory.
    dsttmp=$dstdir/_inst.$$_
    rmtmp=$dstdir/_rm.$$_
    dsttmp=${dstdirslash}_inst.$$_
    rmtmp=${dstdirslash}_rm.$$_

    # Trap to clean up those temp files at exit.
    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0

    # Copy the file name to the temp name.
    (umask $cp_umask &&
     { test -z "$stripcmd" || {
	 # Create $dsttmp read-write so that cp doesn't create it read-only,
	 # which would cause strip to fail.
	 if test -z "$doit"; then
	   : >"$dsttmp" # No need to fork-exec 'touch'.
	 else
	   $doit touch "$dsttmp"
	 fi
       }
     } &&
    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
     $doit_exec $cpprog "$src" "$dsttmp") &&

    # and set any options; do chmod last to preserve setuid bits.
    #
    # If any of these fail, we abort the whole thing.  If we want to
    # ignore errors from any of these, just make sure not to ignore
    # errors from the above "$doit $cpprog $src $dsttmp" command.
    #
    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&

    # If -C, don't bother to copy if it wouldn't change the file.
    if $copy_on_change &&
       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&

       eval "$initialize_posix_glob" &&
       $posix_glob set -f &&
       set -f &&
       set X $old && old=:$2:$4:$5:$6 &&
       set X $new && new=:$2:$4:$5:$6 &&
       $posix_glob set +f &&
       set +f &&

       test "$old" = "$new" &&
       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
    then
      rm -f "$dsttmp"
    else
      # Rename the file to the real destination.
      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||

      # The rename failed, perhaps because mv can't rename something else
      # to itself, or perhaps because mv is so ancient that it does not
      # support -f.
      {
	# Now remove or move aside any old file at destination location.
	# We try this two ways since rm can't unlink itself on some
	# systems and the destination file might be busy for other
	# reasons.  In this case, the final cleanup might fail but the new
	# file should still install successfully.
	{
	  test ! -f "$dst" ||
	  $doit $rmcmd -f "$dst" 2>/dev/null ||
	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
	  } ||
	  { echo "$0: cannot unlink or rename $dst" >&2
	    (exit 1); exit 1
	  }
	} &&
        # Now remove or move aside any old file at destination location.
        # We try this two ways since rm can't unlink itself on some
        # systems and the destination file might be busy for other
        # reasons.  In this case, the final cleanup might fail but the new
        # file should still install successfully.
        {
          test ! -f "$dst" ||
          $doit $rmcmd -f "$dst" 2>/dev/null ||
          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
          } ||
          { echo "$0: cannot unlink or rename $dst" >&2
            (exit 1); exit 1
          }
        } &&

	# Now rename the file to the real destination.
	$doit $mvcmd "$dsttmp" "$dst"
        # Now rename the file to the real destination.
        $doit $mvcmd "$dsttmp" "$dst"
      }
    fi || exit 1

    trap '' 0
  fi
done

# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

Changes to unix/installManPage.

113
114
115
116
117
118
119
120

121
122
123
124
125
113
114
115
116
117
118
119

120
121
122
123
124
125







-
+





    if test -z "$First" ; then
	First=$Target
	sed -e "/man\.macros/r $SrcDir/man.macros" -e "/man\.macros/d" \
	    $ManPage > "$Dir/$First"
	chmod 644 "$Dir/$First"
	$Gzip "$Dir/$First"
    else
	ln "$SymOrLoc$First$Gz" "$Dir/$Target$Gz"
	ln $SymOrLoc"$First$Gz" "$Dir/$Target$Gz"
    fi
done

########################################################################
exit 0

Changes to unix/tcl.m4.

24
25
26
27
28
29
30
31

32
33

34
35
36
37
38
39
40
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 )
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 )
504
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
605
606
607
608
609
610
611
612

613
614
615
616
617
618
619
597
598
599
600
601
602
603

604
605
606
607
608
609
610
611







-
+







#		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
656
657
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







-
+










-
-
+
+







#
#	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
708
709
710
711
712
713
714

715
716


717
718
719
720
721
722

723
724
725
726
727
728
729

730
731
732
733
734
735
736
737
738
739
740
741
742
743

744
745
746
747
748
749
750

751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778







-
+

-
-
+
+




-
+






-
+













-
+






-
+



















+







#			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.
#
# Arguments:
#	none
#
# Results:
#	Defines the following var:
#
#	system -	System/platform/version identification code.
#
#--------------------------------------------------------------------

AC_DEFUN([SC_CONFIG_SYSTEM], [
    AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
	if test "${TEA_PLATFORM}" = "windows" ; then
	    tcl_cv_sys_version=windows
	else
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
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







-
+








-
+












-
+

+
-
-
+
+












-
+








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
956
957
958
959
960
961
962

963
964
965
966
967

968
969
970
971
972
973
974
975







-
+




-
+







    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 -Wwrite-strings -Wpointer-arith"
	CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith -finput-charset=UTF-8"
	case "${CC}" in
	    *++|*++-*)
		;;
	    *)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -Wdeclaration-after-statement"
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -fextended-identifiers"
		;;
	esac

    ], [
	CFLAGS_OPTIMIZE=-O
	CFLAGS_WARNING=""
    ])
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
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







-
+














-
+



-
-
-
+
+
+







	    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
	    do64bit_ok=yes
	    if test "x${SHARED_BUILD}" = "x1"; then
		echo "running cd ../win; ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args"
1286
1287
1288
1289
1290
1291
1292
1293

1294
1295
1296
1297
1298
1299
1300
1280
1281
1282
1283
1284
1285
1286

1287
1288
1289
1290
1291
1292
1293
1294







-
+







		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'])
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
	    AS_IF([test $do64bit = yes], [
		AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
		    hold_cflags=$CFLAGS
		    CFLAGS="$CFLAGS -m64"
		    AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
		    AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[tcl_cv_cc_m64=yes],[tcl_cv_cc_m64=no])
		    CFLAGS=$hold_cflags])
		AS_IF([test $tcl_cv_cc_m64 = yes], [
		    CFLAGS="$CFLAGS -m64"
		    do64bit_ok=yes
		])
	   ])

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







+
-
-
+
+










+
-
-
+
+


















+
-
+












+
-
-
+
+

















-
+
















-
-
-
-
+
+
+
+
















-
-
-
-
+
+
+
+







	    AS_IF([test $do64bit = yes], [
		case `arch` in
		    ppc)
			AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
				tcl_cv_cc_arch_ppc64, [
			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
			    AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
			    AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
				    tcl_cv_cc_arch_ppc64=no)
				    [tcl_cv_cc_arch_ppc64=yes],
				    [tcl_cv_cc_arch_ppc64=no])
			    CFLAGS=$hold_cflags])
			AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [
			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
			    do64bit_ok=yes
			]);;
		    i386)
			AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
				tcl_cv_cc_arch_x86_64, [
			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch x86_64"
			    AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
			    AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
				    tcl_cv_cc_arch_x86_64=no)
				    [tcl_cv_cc_arch_x86_64=yes],
				    [tcl_cv_cc_arch_x86_64=no])
			    CFLAGS=$hold_cflags])
			AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [
			    CFLAGS="$CFLAGS -arch x86_64"
			    do64bit_ok=yes
			]);;
		    *)
			AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
		esac
	    ], [
		# Check for combined 32-bit and 64-bit fat build
		AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
		    && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
		    fat_32_64=yes])
	    ])
	    SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS}'
	    AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
		AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[int i;]])],[tcl_cv_ld_single_module=yes],
		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"
	    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])
		    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"
1725
1726
1727
1728
1729
1730
1731
1732

1733
1734
1735
1736
1737
1738
1739
1723
1724
1725
1726
1727
1728
1729

1730
1731
1732
1733
1734
1735
1736
1737







-
+







	    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)
		AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[int i;]])],[tcl_cv_ld_Bexport=yes],[tcl_cv_ld_Bexport=no])
	        LDFLAGS=$hold_ldflags])
	    AS_IF([test $tcl_cv_ld_Bexport = yes], [
		LDFLAGS="$LDFLAGS -Wl,-Bexport"
	    ])
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
1752
1753
1754
1755
1756
1757
1758
1759

1760
1761
1762
1763
1764
1765
1766
1750
1751
1752
1753
1754
1755
1756

1757
1758
1759
1760
1761
1762
1763
1764







-
+







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
1777
1778
1779
1780
1781
1782
1783

1784
1785
1786
1787
1788

1789
1790
1791
1792
1793
1794
1795
1796







-
+




-
+







    # 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_*) ;;
	    CYGWIN_*|MINGW32_*|MSYS_*) ;;
	    HP_UX*) ;;
	    Darwin-*) ;;
	    IRIX*) ;;
	    Linux*|GNU*) ;;
	    NetBSD-*|OpenBSD-*) ;;
	    NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
	    OSF1-V*) ;;
	    SCO_SV-3.2*) ;;
	    *) SHLIB_CFLAGS="-fPIC" ;;
	esac])

    AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
	AC_DEFINE(MODULE_SCOPE, [extern],
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
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







-
+
-


-
-
-
+
+
+




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

















+








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

    AC_CHECK_HEADER(stdbool.h, [AC_DEFINE(HAVE_STDBOOL_H, 1, [Do we have <stdbool.h>?])],)

    # FIXME: This subst was left in only because the TCL_DL_LIBS
    # entry in tclConfig.sh uses it. It is not clear why someone
    # would use TCL_DL_LIBS instead of TCL_LIBS.
    AC_SUBST(DL_LIBS)

    AC_SUBST(DL_OBJS)
    AC_SUBST(PLAT_OBJS)
    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)

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







-
-
+
+

















-
+







#		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(stdlib.h, tcl_ok=1, tcl_ok=0)
    AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
1969
1970
1971
1972
1973
1974
1975
1976

1977
1978
1979
1980
1981
1982
1983
1980
1981
1982
1983
1984
1985
1986

1987
1988
1989
1990
1991
1992
1993
1994







-
+







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







-
+









-
+







#--------------------------------------------------------------------

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







-
+




-
-
+
+
+





-
-
+
+
+









-
-
+
+

-
-
+
+







-
-
+
+

-
-
+
+










-
-
+
+
+







#		HAVE_TM_TZADJ
#		HAVE_TIMEZONE_VAR
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TIME_HANDLER], [
    AC_CHECK_HEADERS(sys/time.h)
    AC_HEADER_TIME
    AC_CHECK_HEADERS_ONCE([sys/time.h])

    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; 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>]],
	[[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>]],
	    [[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) or thread library
#	(-lpthread) are dealt with here.
#
# Arguments:
#	None.
#
# Results:
#
#	Sets the following vars:
2309
2310
2311
2312
2313
2314
2315

2316

2317
2318
2319
2320



2321
2322
2323
2324
2325
2326
2327
2323
2324
2325
2326
2327
2328
2329
2330

2331




2332
2333
2334
2335
2336
2337
2338
2339
2340
2341







+
-
+
-
-
-
-
+
+
+







#		_LARGEFILE64_SOURCE
#		_LARGEFILE_SOURCE64
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_EARLY_FLAG],[
    AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$2]], [[$3]])],
	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[ 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])
	tcl_flags="$tcl_flags $1"
    fi
])

AC_DEFUN([SC_TCL_EARLY_FLAGS],[
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
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







-










-
-
-



-
-
-
+
+
+




-
-
-
-


-
-
-
+
+
+





-
-
-
-
+
+
+
+





-
-
-
+
+
+







-
-
-
+
+
+







# Arguments:
#	None
#
# Results:
#
#	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
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_64BIT_FLAGS], [
    AC_MSG_CHECKING([for 64-bit integer type])
    AC_CACHE_VAL(tcl_cv_type_64bit,[
	tcl_cv_type_64bit=none
	# See if the compiler knows natively about __int64
	AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
	    tcl_type_64bit=__int64, tcl_type_64bit="long long")
	# See if we could use long anyway  Note that we substitute in the
	# type that is our current guess for a 64-bit type inside this check
	# program, so it should be modified only carefully...
        AC_TRY_COMPILE(,[switch (0) {
            case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ;
        }],tcl_cv_type_64bit=${tcl_type_64bit})])
        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[switch (0) {
            case 1: case (sizeof(long long)==sizeof(long)): ;
        }]])],[tcl_cv_type_64bit="long long"],[])])
    if test "${tcl_cv_type_64bit}" = none ; then
	AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Do 'long' and 'long long' have the same size (64-bit)?])
	AC_MSG_RESULT([yes])
    else
	AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
	    [What type should be used to define wide integers?])
	AC_MSG_RESULT([${tcl_cv_type_64bit}])

	# Now check for auxiliary declarations
	AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
	    AC_TRY_COMPILE([#include <sys/types.h>
#include <dirent.h>],[struct dirent64 p;],
		tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
	    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
	    AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
	    AC_MSG_RESULT([yes])
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449



2450
2451
2452
2453
2454
2455

2456
2457
2458
2459
2460
2461
2462
2446
2447
2448
2449
2450
2451
2452



2453
2454
2455
2456
2457
2458
2459
2460

2461
2462
2463
2464
2465
2466
2467
2468







-
-
-
+
+
+





-
+







#	Will define the following vars:
#		TCL_CFGVAL_ENCODING
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_CFG_ENCODING], [
    AC_ARG_WITH(encoding,
	AC_HELP_STRING([--with-encoding],
	    [encoding for configuration values (default: iso8859-1)]),
	with_tcencoding=${withval})
	AS_HELP_STRING([--with-encoding],
	    [encoding for configuration values (default: utf-8)]),
	[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",
	AC_DEFINE(TCL_CFGVAL_ENCODING,"utf-8",
	    [What encoding should be used for embedded configuration info?])
    fi
])

#--------------------------------------------------------------------
# SC_TCL_CHECK_BROKEN_FUNC
#
2473
2474
2475
2476
2477
2478
2479
2480

2481
2482
2483
2484


2485
2486
2487
2488
2489
2490
2491
2479
2480
2481
2482
2483
2484
2485

2486
2487
2488


2489
2490
2491
2492
2493
2494
2495
2496
2497







-
+


-
-
+
+







#
#--------------------------------------------------------------------

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







-
+

-
+










-
+






-
+

-
+










-
+








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







-
+

-
+







-
+






-
+

-
+







-
+






-
+

-
+





-
+








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







-
+


-
+






-
+






-
+


-
+






-
+







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







-
+


-
+






-
+






-
+


-
+






-
+







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







-
+


-
+






-
+






-
+


-
+






-
+







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







-
+


-
+






-
+






-
+


-
+






-
+







#		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

Changes to unix/tkAppInit.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







+







 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#undef BUILD_tk
#undef STATIC_BUILD
#include "tk.h"
#include "tkPort.h"

#ifdef TK_TEST
#ifdef __cplusplus
extern "C" {
#endif
extern Tcl_PackageInitProc Tktest_Init;
#ifdef __cplusplus
32
33
34
35
36
37
38



39


40
41
42
43
44
45
46
33
34
35
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50
51







+
+
+
-
+
+







 * #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.,
115
116
117
118
119
120
121







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







+
+
+
+
+
+
+







	return TCL_ERROR;
    }

    if (Tk_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit);

#if defined(USE_CUSTOM_EXIT_PROC)
    if (TkpWantsExitProc()) {
	/* The cast below avoids warnings from old gcc compilers. */
	Tcl_SetExitProc((void *)TkpExitProc);
    }
#endif

#ifdef TK_TEST
    if (Tktest_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "Tktest", Tktest_Init, 0);
#endif /* TK_TEST */

Changes to unix/tkConfig.h.in.

1
2
3
4
5



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

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


42
43
44
45

46
47

48
49
50



51
52
53
54
55
56
57
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

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



37
38
39


40
41
42



43


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





+
+
+
















-
+











-
-
-



-
-
+
+

-
-
-
+
-
-
+



+
+
+







/* ../unix/tkConfig.h.in.  Generated from configure.ac by autoheader.  */


    #ifndef _TKCONFIG
    #define _TKCONFIG

/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD

/* Define to 1 if you have the <AvailabilityMacros.h> header file. */
#undef HAVE_AVAILABILITYMACROS_H

/* Defined when compiler supports casting to union type. */
#undef HAVE_CAST_TO_UNION

/* Do we have access to Darwin CoreFoundation.framework? */
#undef HAVE_COREFOUNDATION

/* Is 'DIR64' in <sys/types.h>? */
#undef HAVE_DIR64

/* Compiler support for module scope symbols */
#undef HAVE_HIDDEN

/* Do we have the intptr_t type? */
/* Define to 1 if the system has the type `intptr_t'. */
#undef HAVE_INTPTR_T

/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H

/* Define to 1 if you have the `Xft' library (-lXft). */
#undef HAVE_LIBXFT

/* Define to 1 if you have the `lseek64' function. */
#undef HAVE_LSEEK64

/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H

/* Define to 1 if you have the `open64' function. */
#undef HAVE_OPEN64

/* Define to 1 if you have the `pthread_atfork' function. */
#undef HAVE_PTHREAD_ATFORK
/* Does struct password have a pw_gecos field? */
#undef HAVE_PW_GECOS

/* Define to 1 if you have the `pthread_attr_setstacksize' function. */
#undef HAVE_PTHREAD_ATTR_SETSTACKSIZE

/* Do we have <stdbool.h>? */
/* Does struct password have a pw_gecos field? */
#undef HAVE_PW_GECOS
#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 <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

75
76
77
78
79
80
81
82

83
84
85
86
87
88
89
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89







-
+








/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H

/* Is off64_t in <sys/types.h>? */
#undef HAVE_TYPE_OFF64_T

/* Do we have the uintptr_t type? */
/* Define to 1 if the system has the type `uintptr_t'. */
#undef HAVE_UINTPTR_T

/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H

/* Is weak import available? */
#undef HAVE_WEAK_IMPORT
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128



129
130
131
132
133
134
135
136



137
138
139
140
141
142
143
108
109
110
111
112
113
114



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

136
137
138
139
140
141
142
143
144
145







-
-
-











+
+
+







-
+
+
+








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

/* Define to the full name and version of this package. */
#undef PACKAGE_STRING

/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME

/* Define to the home page for this package. */
#undef PACKAGE_URL

/* Define to the version of this package. */
#undef PACKAGE_VERSION

/* Is this a static build? */
#undef STATIC_BUILD

/* Define to 1 if you have the ANSI C header files. */
/* Define to 1 if all of the C90 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
153
154
155
156
157
158
159
160
161
162

163
164

165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180











181
182
183
184
185
186
187
155
156
157
158
159
160
161



162


163
164



165
166
167
168
169
170






171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188







-
-
-
+
-
-
+

-
-
-






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








/* Is memory debugging enabled? */
#undef TCL_MEM_DEBUG

/* What is the default extension for shared libraries? */
#undef TCL_SHLIB_EXT

/* Are wide integers to be implemented with C 'long's? */
#undef TCL_WIDE_INT_IS_LONG

/* Do 'long' and 'long long' have the same size (64-bit)? */
/* What type should be used to define wide integers? */
#undef TCL_WIDE_INT_TYPE
#undef TCL_WIDE_INT_IS_LONG

/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME

/* Is Tk built as a framework? */
#undef TK_FRAMEWORK

/* Are TkAqua debug messages enabled? */
#undef TK_MAC_DEBUG

/* Do we want to use the threaded memory allocator? */
#undef USE_THREAD_ALLOC

/* Define to 1 if your processor stores words with the most significant byte
   first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
   significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
#  define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
#  undef WORDS_BIGENDIAN
# endif
#endif

/* Are Darwin SUSv3 extensions available? */
#undef _DARWIN_C_SOURCE

/* Add the _ISOC99_SOURCE flag when building */
#undef _ISOC99_SOURCE

196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212


213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

233
234
235

236
237
238
239
240
241
242
243
244
245
246
247
248
249



250
197
198
199
200
201
202
203



204
205
206
207
208
209

210
211
212
213
214
215



216
217
218
219
220
221



222
223
224

225
226
227

228
229
230






231
232
233
234


235
236
237
238







-
-
-






-
+
+




-
-
-






-
-
-



-
+


-
+


-
-
-
-
-
-




-
-
+
+
+


/* Do we really want to follow the standard? Yes we do! */
#undef _POSIX_PTHREAD_SEMANTICS

/* Do we want the reentrant OS API? */
#undef _REENTRANT

/* Do we want the thread-safe OS API? */
#undef _THREAD_SAFE

/* Do we want to use the XOPEN network library? */
#undef _XOPEN_SOURCE

/* Do we want to use the XOPEN network library? */
#undef _XOPEN_SOURCE_EXTENDED

/* Define to 1 if type `char' is unsigned and you are not using gcc.  */
/* 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. */
#undef gid_t

/* Define to `__inline__' or `__inline' if that's what the C compiler
   calls it, or to nothing if 'inline' is not supported under any name.  */
#ifndef __cplusplus
#undef inline
#endif

/* Signed integer type wide enough to hold a pointer. */
#undef intptr_t

/* Define to `int' if <sys/types.h> does not define. */
#undef mode_t

/* Define to `int' if <sys/types.h> does not define. */
/* Define as a signed integer type capable of holding a process identifier. */
#undef pid_t

/* Define to `unsigned' if <sys/types.h> does not define. */
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t

/* Define to `int' if <sys/types.h> doesn't define. */
#undef uid_t

/* Unsigned integer type wide enough to hold a pointer. */
#undef uintptr_t


    /* Undef unused package specific autoheader defines so that we can
     * include both tclConfig.h and tkConfig.h at the same time: */
    /* override */ #undef PACKAGE_NAME
    /* override */ #undef PACKAGE_STRING
    /* override */ #undef PACKAGE_TARNAME
    /* override */ #undef PACKAGE_TARNAME
    /* override */ #undef PACKAGE_VERSION
    /* override */ #undef PACKAGE_STRING
    #endif /* _TKCONFIG */

Changes to unix/tkUnix.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







-
+










-
+







/*
 * tkUnix.c --
 *
 *	This file contains procedures that are UNIX/X-specific, and will
 *	probably have to be written differently for Windows or Macintosh
 *	platforms.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 * Copyright © 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#ifdef HAVE_XSS
#   include <X11/extensions/scrnsaver.h>
#   ifdef __APPLE__
/* Support for weak-linked libXss. */
#	define HaveXSSLibrary()	(XScreenSaverQueryInfo != NULL)
#	define HaveXSSLibrary()	(&XScreenSaverQueryInfo != NULL)
#   else
/* Other platforms always link libXss. */
#	define HaveXSSLibrary()	(1)
#   endif
#endif

/*

Changes to unix/tkUnix3d.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






-
+







/*
 * 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 © 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"

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 © 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"
322
323
324
325
326
327
328
329

330
331
332
333
334
335
336
337
338
339
322
323
324
325
326
327
328

329
330


331
332
333
334
335
336
337







-
+

-
-







 *	Registers an event handler for the widget.
 *
 *----------------------------------------------------------------------
 */

TkButton *
TkpCreateButton(
    Tk_Window tkwin)
    TCL_UNUSED(Tk_Window))
{
    (void)tkwin;

    return (TkButton *)ckalloc(sizeof(UnixButton));
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayButton --
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
801
802
803
804
805
806
807


808
809
810
811
812
813
814







-
-







	 */

	Tk_Draw3DRectangle(tkwin, pixmap, border, inset, inset,
		Tk_Width(tkwin) - 2*inset, Tk_Height(tkwin) - 2*inset,
		butPtr->borderWidth, relief);
    }
    if (butPtr->highlightWidth > 0) {
	GC gc;

	if (butPtr->flags & GOT_FOCUS) {
	    gc = Tk_GCForColor(butPtr->highlightColorPtr, pixmap);
	} else {
	    gc = Tk_GCForColor(Tk_3DBorderColor(butPtr->highlightBorder),
		    pixmap);
	}

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

Changes to unix/tkUnixConfig.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






-
+







/*
 * tkUnixConfig.c --
 *
 *	This module implements the Unix system defaults for the configuration
 *	package.
 *
 * Copyright (c) 1997 by Sun Microsystems, Inc.
 * Copyright © 1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

Changes to unix/tkUnixCursor.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





-
+







/*
 * tkUnixCursor.c --
 *
 *	This file contains X specific cursor manipulation routines.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

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
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44







+











+







 * The definitions below provide symbolic names for the default colors.
 * NORMAL_BG -		Normal background color.
 * ACTIVE_BG -		Background color when widget is active.
 * SELECT_BG -		Background color for selected text.
 * TROUGH -		Background color for troughs in scales and scrollbars.
 * INDICATOR -		Color for indicator when button is selected.
 * DISABLED -		Foreground color when widget is disabled.
 * PLACEHOLDER_FG -	Foreground color for placeholder text.
 */

#define BLACK		"#000000"
#define WHITE		"#ffffff"

#define NORMAL_BG	"#d9d9d9"
#define ACTIVE_BG	"#ececec"
#define SELECT_BG	"#c3c3c3"
#define TROUGH		"#b3b3b3"
#define INDICATOR	WHITE
#define DISABLED	"#a3a3a3"
#define PLACEHOLDER_FG	"#b3b3b3"	/* grey70 */

/*
 * Defaults for labels, buttons, checkbuttons, and radiobuttons:
 */

#define DEF_BUTTON_ANCHOR		"center"
#define DEF_BUTTON_ACTIVE_BG_COLOR	ACTIVE_BG
149
150
151
152
153
154
155
156

157
158
159
160
161
162
163
151
152
153
154
155
156
157

158
159
160
161
162
163
164
165







-
+







#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		"#b3b3b3"
#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"

Changes to unix/tkUnixDialog.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





-
+







/*
 * tkUnixDialog.c --
 *
 *	Contains the Unix implementation of the common dialog boxes:
 *
 * Copyright (c) 1996 Sun Microsystems, Inc.
 * Copyright © 1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkUnixInt.h"

Changes to unix/tkUnixDraw.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





-
+







/*
 * tkUnixDraw.c --
 *
 *	This file contains X specific drawing routines.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 * Copyright © 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

Changes to unix/tkUnixEmbed.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








-
+







/*
 * tkUnixEmbed.c --
 *
 *	This file contains platform-specific functions for UNIX to provide
 *	basic operations needed for application embedding (where one
 *	application can use as its main window an internal window from some
 *	other application). Also includes code to support busy windows.
 *
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 * Copyright © 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkUnixInt.h"
#include "tkBusy.h"

Changes to unix/tkUnixEvent.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






-
+







/*
 * tkUnixEvent.c --
 *
 *	This file implements an event source for X displays for the UNIX
 *	version of Tk.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkUnixInt.h"
#include <signal.h>

Changes to unix/tkUnixFocus.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






-
+







/*
 * tkUnixFocus.c --
 *
 *	This file contains platform specific functions that manage focus for
 *	Tk.
 *
 * Copyright (c) 1997 Sun Microsystems, Inc.
 * Copyright © 1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkUnixInt.h"

Changes to unix/tkUnixFont.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






-
+







/*
 * tkUnixFont.c --
 *
 *	Contains the Unix implementation of the platform-independent font
 *	package interface.
 *
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 * Copyright © 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkUnixInt.h"
#include "tkFont.h"
701
702
703
704
705
706
707
708

709
710
711
712
713
714
715
701
702
703
704
705
706
707

708
709
710
711
712
713
714
715







-
+







	 * out and lost. But make sure we don't have an "-option value" string
	 * since TkFontParseXLFD would return a false success when attempting
	 * to parse it.
	 */

	if (name[0] == '-') {
	    if (name[1] != '*') {
		char *dash;
		const char *dash;

		dash = strchr(name + 1, '-');
		if ((dash == NULL) || (isspace(UCHAR(dash[-1])))) {
		    return NULL;
		}
	    }
	} else if (name[0] != '*') {
1369
1370
1371
1372
1373
1374
1375



1376
1377
1378
1379
1380
1381
1382
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385







+
+
+







 *
 * TkpDrawCharsInContext --
 *
 *	Draw a string of characters on the screen like Tk_DrawChars(), but
 *	with access to all the characters on the line for context. On X11 this
 *	context isn't consulted, so we just call Tk_DrawChars().
 *
 *      Note: TK_DRAW_IN_CONTEXT being currently defined only on macOS, this
 *            function is unused (and possibly unfinished). See [7655f65ae7].
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Information gets drawn on the screen.
 *
 *---------------------------------------------------------------------------
1405
1406
1407
1408
1409
1410
1411
































1412
1413
1414
1415
1416
1417
1418
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







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







{
    int widthUntilStart;

    Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart);
    Tk_DrawChars(display, drawable, gc, tkfont, source + rangeStart,
	    rangeLength, x+widthUntilStart, y);
}

void
TkpDrawAngledCharsInContext(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn; must
				 * be the same as font used in GC. */
    const char * source,	/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that is
				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int rangeStart,		/* Index of first byte to draw. */
    int rangeLength,		/* Length of range to draw in bytes. */
    double x, double y,		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
    double angle)		/* What angle to put text at, in degrees. */
{
    int widthUntilStart;
    double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0);

    (void) numBytes; /*unused*/

    Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart);
    TkDrawAngledChars(display, drawable, gc, tkfont, source + rangeStart,
	    rangeLength, x+cosA*widthUntilStart, y-sinA*widthUntilStart, angle);
}

/*
 *-------------------------------------------------------------------------
 *
 * CreateClosestFont --
 *
 *	Helper for TkpGetNativeFont() and TkpGetFontFromAttributes(). Given a
1674
1675
1676
1677
1678
1679
1680
1681

1682
1683
1684
1685
1686
1687
1688
1709
1710
1711
1712
1713
1714
1715

1716
1717
1718
1719
1720
1721
1722
1723







-
+







	/*
	 * If the XA_UNDERLINE_THICKNESS property does not exist, the X manual
	 * recommends using the width of the stem on a capital letter. I don't
	 * know of a way to get the stem width of a letter, so guess and use
	 * 1/3 the width of a capital I.
	 */

	fontPtr->barHeight = fontPtr->widths['I'] / 3;
	fontPtr->barHeight = fontPtr->widths[(unsigned char)'I'] / 3;
	if (fontPtr->barHeight == 0) {
	    fontPtr->barHeight = 1;
	}
    }
    if (fontPtr->underlinePos + fontPtr->barHeight > fontStructPtr->descent) {
	/*
	 * If this set of cobbled together values would cause the bottom of
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080




2081
2082
2083
2084
2085
2086
2087
2105
2106
2107
2108
2109
2110
2111




2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122







-
-
-
-
+
+
+
+







    /*
     * Try all face names available in the whole system until we find one that
     * can be used.
     */

    nameList = ListFonts(fontPtr->display, "*", &numNames);
    for (i = 0; i < numNames; i++) {
	fallback = strchr(nameList[i] + 1, '-') + 1;
	strchr(fallback, '-')[0] = '\0';
	if (SeenName(fallback, &ds) == 0) {
	    subFontPtr = CanUseFallback(fontPtr, fallback, ch,
	char *fallbck = strchr(nameList[i] + 1, '-') + 1;
	strchr(fallbck, '-')[0] = '\0';
	if (SeenName(fallbck, &ds) == 0) {
	    subFontPtr = CanUseFallback(fontPtr, fallbck, ch,
		    fixSubFontPtrPtr);
	    if (subFontPtr != NULL) {
		XFreeFontNames(nameList);
		goto end;
	    }
	}
    }

Changes to unix/tkUnixInit.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





-
+







/*
 * tkUnixInit.c --
 *
 *	This file contains Unix-specific interpreter initialization functions.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkUnixInt.h"

37
38
39
40
41
42
43


44
45
46
47
48
49
50
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52







+
+








int
TkpInit(
    Tcl_Interp *interp)
{
    TkCreateXEventSource();
    GetLibraryPath(interp);
    Tktray_Init(interp);
    (void)SysNotify_Init (interp);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetAppName --

Changes to unix/tkUnixInt.h.

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
35
36
37
38







+
+
+

+







/*
 * Prototypes for procedures that are referenced in files other than the ones
 * they're defined in.
 */

#include "tkIntPlatDecls.h"

MODULE_SCOPE  int       Tktray_Init (Tcl_Interp* interp);
MODULE_SCOPE  int       SysNotify_Init (Tcl_Interp* interp);

#endif /* _TKUNIXINT */


/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:

Changes to unix/tkUnixKey.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






-
+







/*
 * tkUnixKey.c --
 *
 *	This file contains routines for dealing with international keyboard
 *	input.
 *
 * Copyright (c) 1997 by Sun Microsystems, Inc.
 * Copyright © 1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

299
300
301
302
303
304
305








306
307
308
309
310
311
312
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320







+
+
+
+
+
+
+
+







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

    /*
     * Refresh the mapping information if it's stale. This must happen before
     * we do any input method processing. [Bug 3599312]
     */

    if (dispPtr->bindInfoStale) {

Changes to unix/tkUnixMenu.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
18
19
20





-
+







-







/*
 * tkUnixMenu.c --
 *
 *	This module implements the UNIX platform-specific features of menus.
 *
 * Copyright (c) 1996-1998 by Sun Microsystems, Inc.
 * Copyright © 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 "tkUnixInt.h"
#include "tkMenu.h"
#include "default.h"

/*
 * Constants used for menu drawing.
 */

#define MENU_MARGIN_WIDTH	2
#define MENU_DIVIDER_HEIGHT	2
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156
157
158
140
141
142
143
144
145
146

147
148


149
150
151
152
153
154
155







-
+

-
-







 *	All platform-specific allocations are freed up.
 *
 *----------------------------------------------------------------------
 */

void
TkpDestroyMenu(
    TkMenu *menuPtr)
    TCL_UNUSED(TkMenu *))
{
    (void)menuPtr;

    /*
     * Nothing to do.
     */
}

/*
 *----------------------------------------------------------------------
169
170
171
172
173
174
175
176

177
178
179
180
181
182
183
184
185
186
166
167
168
169
170
171
172

173
174


175
176
177
178
179
180
181







-
+

-
-







 *	All platform specific allocations are freed up.
 *
 *----------------------------------------------------------------------
 */

void
TkpDestroyMenuEntry(
    TkMenuEntry *mEntryPtr)
    TCL_UNUSED(TkMenuEntry *))
{
    (void)mEntryPtr;

    /*
     * Nothing to do.
     */
}

/*
 *----------------------------------------------------------------------
239
240
241
242
243
244
245
246

247
248
249
250
251
252
253
254
255
256
234
235
236
237
238
239
240

241
242


243
244
245
246
247
248
249







-
+

-
-







 *	None on Unix.
 *
 *----------------------------------------------------------------------
 */

int
TkpMenuNewEntry(
    TkMenuEntry *mePtr)
    TCL_UNUSED(TkMenuEntry *))
{
    (void)mePtr;

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpSetWindowMenuBar --
294
295
296
297
298
299
300
301
302
303



304
305
306
307
308
309
310
311
312
313
314
315
287
288
289
290
291
292
293



294
295
296
297




298
299
300
301
302
303
304







-
-
-
+
+
+

-
-
-
-







 *	Recompute geometry of given window.
 *
 *----------------------------------------------------------------------
 */

void
TkpSetMainMenubar(
    Tcl_Interp *interp,
    Tk_Window tkwin,
    const char *menuName)
    TCL_UNUSED(Tcl_Interp *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(const char *))
{
    (void)interp;
    (void)tkwin;
    (void)menuName;

    /*
     * Nothing to do.
     */
}

/*
 *----------------------------------------------------------------------
329
330
331
332
333
334
335
336
337


338
339
340
341
342
343
344
345
346
347
348
349
350
318
319
320
321
322
323
324


325
326
327
328
329
330


331
332
333
334
335
336
337







-
-
+
+




-
-







 *----------------------------------------------------------------------
 */

static void
GetMenuIndicatorGeometry(
    TkMenu *menuPtr,		/* The menu we are drawing. */
    TkMenuEntry *mePtr,		/* The entry we are interested in. */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated metrics */
    TCL_UNUSED(Tk_Font),		/* The precalculated font */
    TCL_UNUSED(const Tk_FontMetrics *),/* The precalculated metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{
    int borderWidth;
    (void)tkfont;
    (void)fmPtr;

    if ((mePtr->type == CHECK_BUTTON_ENTRY)
	    || (mePtr->type == RADIO_BUTTON_ENTRY)) {
	if (!mePtr->hideMargin && mePtr->indicatorOn) {
	    if ((mePtr->image != NULL) || (mePtr->bitmapPtr != NULL)) {
		*widthPtr = (14 * mePtr->height) / 10;
		*heightPtr = mePtr->height;
531
532
533
534
535
536
537
538

539
540
541
542
543
544
545
518
519
520
521
522
523
524

525
526
527
528
529
530
531
532







-
+







	const char *accel = Tcl_GetString(mePtr->accelPtr);
	int left = x + mePtr->labelWidth + activeBorderWidth
		+ mePtr->indicatorSpace;

	if (menuPtr->menuType == MENUBAR) {
	    left += 5;
	}
    	Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel,
	Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel,
		mePtr->accelLength, left,
		(y + (height + fmPtr->ascent - fmPtr->descent) / 2));
    }
}

/*
 *----------------------------------------------------------------------
561
562
563
564
565
566
567
568
569


570
571
572

573
574
575
576
577
578
579
580
581
582
583
584
585
548
549
550
551
552
553
554


555
556
557
558

559
560
561




562
563
564
565
566
567
568







-
-
+
+


-
+


-
-
-
-







DrawMenuEntryIndicator(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* The drawable to draw into */
    Tk_3DBorder border,		/* The background color */
    XColor *indicatorColor,	/* The color to draw indicators with */
    XColor *disableColor,	/* The color use use when disabled */
    Tk_Font tkfont,		/* The font to draw with */
    const Tk_FontMetrics *fmPtr,/* The font metrics of the font */
    TCL_UNUSED(Tk_Font),		/* The font to draw with */
    TCL_UNUSED(const Tk_FontMetrics *),/* The font metrics of the font */
    int x,			/* The left of the entry rect */
    int y,			/* The top of the entry rect */
    int width,			/* Width of menu entry */
    TCL_UNUSED(int),			/* Width of menu entry */
    int height)			/* Height of menu entry */
{
    (void)tkfont;
    (void)fmPtr;
    (void)width;

    /*
     * Draw check-button indicator.
     */

    if ((mePtr->type == CHECK_BUTTON_ENTRY) && mePtr->indicatorOn) {
	int top, left, activeBorderWidth;
	int disabled = (mePtr->state == ENTRY_DISABLED);
634
635
636
637
638
639
640
641

642
643
644
645



646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
617
618
619
620
621
622
623

624
625



626
627
628
629
630
631
632
633





634
635
636
637
638
639
640







-
+

-
-
-
+
+
+





-
-
-
-
-







 *
 *----------------------------------------------------------------------
 */

static 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,			/* The drawable we are using */
    GC gc,			/* The gc to draw into */
    Tk_Font tkfont,		/* The font to draw with */
    const Tk_FontMetrics *fmPtr,/* The font metrics from the font */
    TCL_UNUSED(GC),			/* The gc to draw into */
    TCL_UNUSED(Tk_Font),		/* The font to draw with */
    TCL_UNUSED(const Tk_FontMetrics *),/* The font metrics from the font */
    int x, int y,
    int width, int height)
{
    XPoint points[2];
    Tk_3DBorder border;
    (void)mePtr;
    (void)gc;
    (void)tkfont;
    (void)fmPtr;

    if (menuPtr->menuType == MENUBAR) {
	return;
    }

    points[0].x = x;
    points[0].y = y + height/2;
    points[1].x = x + width - 1;
867
868
869
870
871
872
873
874

875
876
877
878
879
880
881
882
883
884
845
846
847
848
849
850
851

852
853


854
855
856
857
858
859
860







-
+

-
-







    TkMenu *menuPtr,		/* The menu to draw into */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* What we are drawing into */
    GC gc,			/* The gc to draw into */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int x, int y,
    int width, int height)
    TCL_UNUSED(int), int height)
{
    (void)width;

    if ((mePtr->underline >= 0) && (mePtr->labelPtr != NULL)) {
	int len;

	len = Tcl_GetCharLength(mePtr->labelPtr);
	if (mePtr->underline < len) {
	    int activeBorderWidth, leftEdge, ch;
	    const char *label, *start, *end;
948
949
950
951
952
953
954
955

956
957
958
959
960
961
962
963
964
965
966
967
968
969
924
925
926
927
928
929
930

931
932
933
934
935
936
937

938
939
940
941
942
943
944







-
+






-







 *	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 the
				 * specified entry will be posted */
{
    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;
    }
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
1014
1015
1016
1017
1018
1019
1020



1021
1022
1023
1024
1025
1026
1027




1028
1029
1030
1031
1032
1033
1034







-
-
-
+
+
+




-
-
-
-







 *	None.
 *
 *----------------------------------------------------------------------
 */

static 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;
}

/*
 *----------------------------------------------------------------------
 *
1073
1074
1075
1076
1077
1078
1079
1080

1081
1082
1083
1084
1085
1086
1087
1088

1089
1090
1091
1092
1093
1094
1095
1044
1045
1046
1047
1048
1049
1050

1051
1052
1053
1054
1055
1056



1057
1058
1059
1060
1061
1062
1063
1064







-
+





-
-
-
+







 *
 *----------------------------------------------------------------------
 */

static void
GetTearoffEntryGeometry(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TkMenuEntry *mePtr,		/* The entry we are measuring */
    TCL_UNUSED(TkMenuEntry *),		/* The entry we are measuring */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{
    (void)mePtr;

    if (menuPtr->menuType != MASTER_MENU) {
    if (menuPtr->menuType != MAIN_MENU) {
	*heightPtr = 0;
	*widthPtr = 0;
    } else {
	*heightPtr = fmPtr->linespace;
	*widthPtr = Tk_TextWidth(tkfont, "W", 1);
    }
}
1116
1117
1118
1119
1120
1121
1122
1123

1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1085
1086
1087
1088
1089
1090
1091

1092
1093
1094
1095
1096
1097
1098


1099
1100
1101
1102
1103
1104
1105







-
+






-
-







TkpComputeMenubarGeometry(
    TkMenu *menuPtr)		/* Structure describing menu. */
{
    Tk_Font tkfont, menuFont;
    Tk_FontMetrics menuMetrics, entryMetrics, *fmPtr;
    int width, height, i, j, x, y, currentRowHeight, maxWidth;
    int maxWindowWidth, lastRowBreak, lastEntry;
    int borderWidth, activeBorderWidth, helpMenuIndex = -1;
    int activeBorderWidth, helpMenuIndex = -1;
    TkMenuEntry *mePtr;

    if (menuPtr->tkwin == NULL) {
	return;
    }

    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
	    &borderWidth);
    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr,
	    &activeBorderWidth);
    maxWidth = 0;
    if (menuPtr->numEntries == 0) {
	height = 0;
    } else {
	int borderWidth;
1146
1147
1148
1149
1150
1151
1152
1153

1154
1155
1156
1157
1158
1159
1160
1113
1114
1115
1116
1117
1118
1119

1120
1121
1122
1123
1124
1125
1126
1127







-
+







		&borderWidth);
	x = y = borderWidth;
	lastRowBreak = 0;

	/*
	 * On the Mac especially, getting font metrics can be quite slow, so
	 * we want to do it intelligently. We are going to precalculate them
	 * and pass them down to all of the measureing and drawing routines.
	 * and pass them down to all of the measuring and drawing routines.
	 * We will measure the font metrics of the menu once, and if an entry
	 * has a font set, we will measure it as we come to it, and then we
	 * decide which set to give the geometry routines.
	 */

	menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
	Tk_GetFontMetrics(menuFont, &menuMetrics);
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
1260
1261
1262
1263
1264
1265
1266

1267
1268



1269
1270
1271
1272
1273
1274
1275
1276
1277




1278

1279
1280
1281
1282
1283
1284
1285
1286







-
+

-
-
-
+
+
+






-
-
-
-

-
+







 *
 *----------------------------------------------------------------------
 */

static 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 != MASTER_MENU) {
    if (menuPtr->menuType != MAIN_MENU) {
	return;
    }

    points[0].x = x;
    points[0].y = y + height/2;
    points[1].y = points[0].y;
    segmentWidth = 6;
1352
1353
1354
1355
1356
1357
1358
1359
1360


1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1315
1316
1317
1318
1319
1320
1321


1322
1323
1324
1325



1326
1327
1328
1329
1330
1331
1332







-
-
+
+


-
-
-







 *	Alt-key bindings.
 *
 *--------------------------------------------------------------
 */

void
TkpInitializeMenuBindings(
    Tcl_Interp *interp,		/* The interpreter to set. */
    Tk_BindingTable bindingTable)
    TCL_UNUSED(Tcl_Interp *),		/* The interpreter to set. */
    TCL_UNUSED(Tk_BindingTable))
				/* The table to add to. */
{
    (void)interp;
    (void)bindingTable;

    /*
     * Nothing to do.
     */
}

/*
 *----------------------------------------------------------------------
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413



1414
1415

1416
1417

1418
1419
1420

1421
1422
1423
1424
1425
1426
1427
1364
1365
1366
1367
1368
1369
1370



1371
1372
1373
1374

1375
1376

1377
1378
1379

1380
1381
1382
1383
1384
1385
1386
1387







-
-
-
+
+
+

-
+

-
+


-
+







	return;
    }

    for (cascadeEntryPtr = menuPtr->menuRefPtr->parentEntryPtr;
	    cascadeEntryPtr != NULL;
	    cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) {
	if ((cascadeEntryPtr->menuPtr->menuType == MENUBAR)
		&& (cascadeEntryPtr->menuPtr->masterMenuPtr->tkwin != NULL)
		&& (menuPtr->masterMenuPtr->tkwin != NULL)) {
	    TkMenu *masterMenuPtr = cascadeEntryPtr->menuPtr->masterMenuPtr;
		&& (cascadeEntryPtr->menuPtr->mainMenuPtr->tkwin != NULL)
		&& (menuPtr->mainMenuPtr->tkwin != NULL)) {
	    TkMenu *mainMenuPtr = cascadeEntryPtr->menuPtr->mainMenuPtr;
	    char *helpMenuName = (char *)ckalloc(strlen(Tk_PathName(
		    masterMenuPtr->tkwin)) + strlen(".help") + 1);
		    mainMenuPtr->tkwin)) + strlen(".help") + 1);

	    strcpy(helpMenuName, Tk_PathName(masterMenuPtr->tkwin));
	    strcpy(helpMenuName, Tk_PathName(mainMenuPtr->tkwin));
	    strcat(helpMenuName, ".help");
	    if (strcmp(helpMenuName,
		    Tk_PathName(menuPtr->masterMenuPtr->tkwin)) == 0) {
		    Tk_PathName(menuPtr->mainMenuPtr->tkwin)) == 0) {
		cascadeEntryPtr->entryFlags |= ENTRY_HELP_MENU;
	    } else {
		cascadeEntryPtr->entryFlags &= ~ENTRY_HELP_MENU;
	    }
	    ckfree(helpMenuName);
	}
    }
1883
1884
1885
1886
1887
1888
1889
1890
1891


1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1843
1844
1845
1846
1847
1848
1849


1850
1851
1852



1853
1854
1855
1856
1857
1858
1859







-
-
+
+

-
-
-







 *	An idle handler is set up to do the reconfiguration.
 *
 *----------------------------------------------------------------------
 */

void
TkpMenuNotifyToplevelCreate(
    Tcl_Interp *dummy,		/* The interp the menu lives in. */
    const char *menuName)	/* The name of the menu to reconfigure. */
    TCL_UNUSED(Tcl_Interp *),	/* The interp the menu lives in. */
    TCL_UNUSED(const char *))	/* The name of the menu to reconfigure. */
{
    (void)dummy;
    (void)menuName;

    /*
     * Nothing to do.
     */
}

/*
 *----------------------------------------------------------------------

Changes to unix/tkUnixMenubu.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
1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34

35
36


37
38
39
40
41
42
43






-
+




















-
+






-
+

-
-







/*
 * tkUnixMenubu.c --
 *
 *	This file implements the Unix specific portion of the menubutton
 *	widget.
 *
 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
 * Copyright © 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"


/*
 *----------------------------------------------------------------------
 *
 * TkpCreateMenuButton --
 *
 *	Allocate a new TkMenuButton structure.
 *
 * Results:
 *	Returns a newly allocated TkMenuButton structure.
 *
 * Side effects:
 *	Registers an event handler for the widget.
 *	None
 *
 *----------------------------------------------------------------------
 */

TkMenuButton *
TkpCreateMenuButton(
    Tk_Window tkwin)
    TCL_UNUSED(Tk_Window))
{
    (void)tkwin;

    return (TkMenuButton *)ckalloc(sizeof(TkMenuButton));
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayMenuButton --
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
276
277
278
279
280
281
282


283
284
285
286
287
288
289







-
-







	Tk_Draw3DRectangle(tkwin, pixmap, border,
		mbPtr->highlightWidth, mbPtr->highlightWidth,
		Tk_Width(tkwin) - 2*mbPtr->highlightWidth,
		Tk_Height(tkwin) - 2*mbPtr->highlightWidth,
		mbPtr->borderWidth, mbPtr->relief);
    }
    if (mbPtr->highlightWidth != 0) {
	GC gc;

	if (mbPtr->flags & GOT_FOCUS) {
	    gc = Tk_GCForColor(mbPtr->highlightColorPtr, pixmap);
	} else {
	    gc = Tk_GCForColor(mbPtr->highlightBgColorPtr, pixmap);
	}
	Tk_DrawFocusHighlight(tkwin, gc, mbPtr->highlightWidth, pixmap);
    }

Changes to unix/tkUnixPort.h.

32
33
34
35
36
37
38
39
40
41
42
43

44
45
46


47
48
49

50
51
52
53
54
55
56
32
33
34
35
36
37
38





39
40


41
42



43
44
45
46
47
48
49
50







-
-
-
-
-
+

-
-
+
+
-
-
-
+







#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>
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
139
140
141
142
143
144
145


146
147
148
149
150
151
152







-
-








/*
 * These functions do nothing under Unix, so we just eliminate calls to them.
 */

#define TkpButtonSetDefaults() {}
#define TkpDestroyButton(butPtr) {}
#define TkpWillDrawWidget(tkwin) 1
#define TkpRedrawWidget(tkwin)
#define TkSelUpdateClipboard(a,b) {}
#ifndef __CYGWIN__
#define TkSetPixmapColormap(p,c) {}
#endif

/*
 * These calls implement native bitmaps which are not supported under
171
172
173
174
175
176
177






178
163
164
165
166
167
168
169
170
171
172
173
174
175
176







+
+
+
+
+
+

 */

#ifndef __CYGWIN__
#define TkpPrintWindowId(buf,w) \
	sprintf((buf), "%#08lx", (unsigned long) (w))
#endif

/*
 * Used by tkWindow.c
 */

#define TkpHandleMapOrUnmap(tkwin, event)  Tk_HandleEvent(event)

#endif /* _UNIXPORT */

Changes to unix/tkUnixRFont.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





-
+








-







/*
 * tkUnixRFont.c --
 *
 *	Alternate implementation of tkUnixFont.c using Xft.
 *
 * Copyright (c) 2002-2003 Keith Packard
 * Copyright © 2002-2003 Keith Packard
 *
 * 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

typedef struct {
    XftFont *ftFont;
    XftFont *ft0Font;
    FcPattern *source;
204
205
206
207
208
209
210
211

212
213
214
215
216
217
218
203
204
205
206
207
208
209

210
211
212
213
214
215
216
217







-
+







	weight = XFT_WEIGHT_MEDIUM;
    }
    if (XftPatternGetInteger(ftFont->pattern, XFT_SLANT, 0,
	    &slant) != XftResultMatch) {
	slant = XFT_SLANT_ROMAN;
    }

#if DEBUG_FONTSEL
#ifdef DEBUG_FONTSEL
    printf("family %s size %d weight %d slant %d\n",
	    family, (int)size, weight, slant);
#endif /* DEBUG_FONTSEL */

    faPtr->family = Tk_GetUid(family);
    faPtr->size = size;
    faPtr->weight = (weight > XFT_WEIGHT_MEDIUM) ? TK_FW_BOLD : TK_FW_NORMAL;
449
450
451
452
453
454
455
456

457
458
459
460
461
462
463
448
449
450
451
452
453
454

455
456
457
458
459
460
461
462







-
+







TkFont *
TkpGetNativeFont(
    Tk_Window tkwin,		/* For display where font will be used. */
    const char *name)		/* Platform-specific font name. */
{
    UnixFtFont *fontPtr;
    FcPattern *pattern;
#if DEBUG_FONTSEL
#ifdef DEBUG_FONTSEL
    printf("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
486
487
488
489
490
491
492

493
494
495
496
497
498
499
500







-
+







    const TkFontAttributes *faPtr)
				/* Set of attributes to match. */
{
    XftPattern *pattern;
    int weight, slant;
    UnixFtFont *fontPtr;

#if DEBUG_FONTSEL
#ifdef DEBUG_FONTSEL
    printf("TkpGetFontFromAttributes %s-%d %d %d\n", faPtr->family,
	    faPtr->size, faPtr->weight, faPtr->slant);
#endif /* DEBUG_FONTSEL */
    pattern = XftPatternCreate();
    if (faPtr->family) {
	XftPatternAddString(pattern, XFT_FAMILY, faPtr->family);
    }
667
668
669
670
671
672
673
674

675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
666
667
668
669
670
671
672

673
674
675
676
677
678
679
680
681
682
683

684
685
686
687
688
689
690







-
+










-







 *	character.
 *
 *----------------------------------------------------------------------
 */

void
TkpGetFontAttrsForChar(
    Tk_Window tkwin,		/* Window on the font's display */
    TCL_UNUSED(Tk_Window),	/* Window on the font's display */
    Tk_Font tkfont,		/* Font to query */
    int c,         		/* Character of interest */
    TkFontAttributes *faPtr)	/* Output: Font attributes */
{
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
				/* Structure describing the logical font */
    FcChar32 ucs4 = (FcChar32) c;
				/* UCS-4 character to map */
    XftFont *ftFont = GetFont(fontPtr, ucs4, 0.0);
				/* Actual font used to render the character */
    (void)tkwin;

    GetTkFontAttributes(ftFont, faPtr);
    faPtr->underline = fontPtr->font.fa.underline;
    faPtr->overstrike = fontPtr->font.fa.overstrike;
}

int
715
716
717
718
719
720
721
722

723
724
725
726
727
728
729
713
714
715
716
717
718
719

720
721
722
723
724
725
726
727







-
+







    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
    XftFont *ftFont;
    FcChar32 c;
    XGlyphInfo extents;
    int clen, curX, newX, curByte, newByte, sawNonSpace;
    int termByte = 0, termX = 0, errorFlag = 0;
    Tk_ErrorHandler handler;
#if DEBUG_FONTSEL
#ifdef DEBUG_FONTSEL
    char string[256];
    int len = 0;
#endif /* DEBUG_FONTSEL */

    handler = Tk_CreateErrorHandler(fontPtr->display,
	    -1, -1, -1, InitFontErrorProc, &errorFlag);
    curX = 0;
752
753
754
755
756
757
758
759

760
761
762
763
764
765
766
750
751
752
753
754
755
756

757
758
759
760
761
762
763
764







-
+







		termX = curX;
		sawNonSpace = 0;
	    }
	} else {
	    sawNonSpace = 1;
	}

#if DEBUG_FONTSEL
#ifdef DEBUG_FONTSEL
	string[len++] = (char) c;
#endif /* DEBUG_FONTSEL */
	ftFont = GetFont(fontPtr, c, 0.0);

	if (!errorFlag) {
	    XftTextExtents32(fontPtr->display, ftFont, &c, 1, &extents);
	} else {
792
793
794
795
796
797
798
799

800
801
802
803
804
805
806
790
791
792
793
794
795
796

797
798
799
800
801
802
803
804







-
+







	    break;
	}

	curX = newX;
	curByte = newByte;
    }
    Tk_DeleteErrorHandler(handler);
#if DEBUG_FONTSEL
#ifdef DEBUG_FONTSEL
    string[len] = '\0';
    printf("MeasureChars %s length %d bytes %d\n", string, curX, curByte);
#endif /* DEBUG_FONTSEL */
    *lengthPtr = curX;
    return curByte;
}

932
933
934
935
936
937
938
939

940
941
942
943
944
945
946
930
931
932
933
934
935
936

937
938
939
940
941
942
943
944







-
+







    int clen, nspec, xStart = x;
    XftGlyphFontSpec specs[NUM_SPEC];
    XGlyphInfo metrics;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (fontPtr->ftDraw == 0) {
#if DEBUG_FONTSEL
#ifdef DEBUG_FONTSEL
	printf("Switch to drawable 0x%x\n", drawable);
#endif /* DEBUG_FONTSEL */
	fontPtr->ftDraw = XftDrawCreate(display, drawable,
		DefaultVisual(display, fontPtr->screen),
		DefaultColormap(display, fontPtr->screen));
    } else {
	Tk_ErrorHandler handler =
1067
1068
1069
1070
1071
1072
1073
1074

1075
1076
1077
1078
1079
1080
1081
1065
1066
1067
1068
1069
1070
1071

1072
1073
1074
1075
1076
1077
1078
1079







-
+







    int clen, nglyph;
    FT_UInt glyphs[NUM_SPEC];
    XGlyphInfo metrics;
    XftFont *currentFtFont;
    int originX, originY;

    if (fontPtr->ftDraw == 0) {
#if DEBUG_FONTSEL
#ifdef DEBUG_FONTSEL
	printf("Switch to drawable 0x%x\n", drawable);
#endif /* DEBUG_FONTSEL */
	fontPtr->ftDraw = XftDrawCreate(display, drawable,
		DefaultVisual(display, fontPtr->screen),
		DefaultColormap(display, fontPtr->screen));
    } else {
	Tk_ErrorHandler handler =
1176
1177
1178
1179
1180
1181
1182
1183

1184
1185
1186
1187
1188
1189
1190
1174
1175
1176
1177
1178
1179
1180

1181
1182
1183
1184
1185
1186
1187
1188







-
+







#else /* !XFT_HAS_FIXED_ROTATED_PLACEMENT */
    int clen, nspec;
    XftGlyphFontSpec specs[NUM_SPEC];
    XGlyphInfo metrics;
    double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0);

    if (fontPtr->ftDraw == 0) {
#if DEBUG_FONTSEL
#ifdef DEBUG_FONTSEL
	printf("Switch to drawable 0x%x\n", drawable);
#endif /* DEBUG_FONTSEL */
	fontPtr->ftDraw = XftDrawCreate(display, drawable,
		DefaultVisual(display, fontPtr->screen),
		DefaultColormap(display, fontPtr->screen));
    } else {
	Tk_ErrorHandler handler =
1301
1302
1303
1304
1305
1306
1307



















































































1308
1309
1310
1311
1312
1313
1314
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







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







		XFillPolygon(display, drawable, gc, points, 5, Complex,
			CoordModeOrigin);
		XDrawLines(display, drawable, gc, points, 5, CoordModeOrigin);
	    }
	}
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * TkpDrawCharsInContext --
 *
 *	Draw a string of characters on the screen like Tk_DrawChars(), but
 *	with access to all the characters on the line for context. On X11 this
 *	context isn't consulted, so we just call Tk_DrawChars().
 *
 *      Note: TK_DRAW_IN_CONTEXT being currently defined only on macOS, this
 *            function is unused (and possibly unfinished). See [7655f65ae7].
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Information gets drawn on the screen.
 *
 *---------------------------------------------------------------------------
 */

void
TkpDrawCharsInContext(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn;
				 * must be the same as font used in GC. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int rangeStart,		/* Index of first byte to draw. */
    int rangeLength,		/* Length of range to draw in bytes. */
    int x, int y)		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
{
    int widthUntilStart;

    (void) numBytes; /*unused*/

    Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart);
    Tk_DrawChars(display, drawable, gc, tkfont, source + rangeStart,
	    rangeLength, x+widthUntilStart, y);
}

void
TkpDrawAngledCharsInContext(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn; must
				 * be the same as font used in GC. */
    const char * source,	/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that is
				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int rangeStart,		/* Index of first byte to draw. */
    int rangeLength,		/* Length of range to draw in bytes. */
    double x, double y,		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
    double angle)		/* What angle to put text at, in degrees. */
{
    int widthUntilStart;
    double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0);

    (void) numBytes; /*unused*/

    Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart);
    TkDrawAngledChars(display, drawable, gc, tkfont, source + rangeStart,
	    rangeLength, x+cosA*widthUntilStart, y-sinA*widthUntilStart, angle);
}

void
TkUnixSetXftClipRegion(
    Region clipRegion)	/* The clipping region to install. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

Changes to unix/tkUnixScale.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





-
-
+
+







/*
 * tkUnixScale.c --
 *
 *	This file implements the X specific portion of the scrollbar widget.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * Copyright (c) 1998-2000 by Scriptics Corporation.
 * Copyright © 1996 Sun Microsystems, Inc.
 * Copyright © 1998-2000 Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkScale.h"
46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62
63
46
47
48
49
50
51
52

53
54


55
56
57
58
59
60
61







-
+

-
-







 *	None.
 *
 *----------------------------------------------------------------------
 */

TkScale *
TkpCreateScale(
    Tk_Window tkwin)
    TCL_UNUSED(Tk_Window))
{
    (void)tkwin;

    return (TkScale *)ckalloc(sizeof(TkScale));
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDestroyScale --

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

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





-
+







/*
 * tkUnixSelect.c --
 *
 *	This file contains X specific routines for manipulating selections.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkSelect.h"
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







-








    if (eventPtr->type == SelectionNotify) {
	TkSelRetrievalInfo *retrPtr;
	char *propInfo, **propInfoPtr = &propInfo;
	Atom type;
	int format, result;
	unsigned long numItems, bytesAfter;
	Tcl_DString ds;

	for (retrPtr = pendingRetrievals; ; retrPtr = retrPtr->nextPtr) {
	    if (retrPtr == NULL) {
		return;
	    }
	    if ((retrPtr->winPtr == winPtr)
		    && (retrPtr->selection == eventPtr->xselection.selection)
587
588
589
590
591
592
593

594
595
596
597
598
599
600
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600







+







	    retrPtr->result = TCL_ERROR;
	    XFree(propInfo);
	    return;
	}
	if ((type == XA_STRING) || (type == dispPtr->textAtom)
		|| (type == dispPtr->compoundTextAtom)) {
	    Tcl_Encoding encoding;
		Tcl_DString ds;

	    if (format != 8) {
		Tcl_SetObjResult(retrPtr->interp, Tcl_ObjPrintf(
			"bad format for string selection: wanted \"8\", got \"%d\"",
			format));
		Tcl_SetErrorCode(retrPtr->interp, "TK", "SELECTION", "FORMAT",
			NULL);
1518
1519
1520
1521
1522
1523
1524
1525

1526
1527
1528

1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1518
1519
1520
1521
1522
1523
1524

1525
1526
1527

1528
1529
1530



1531
1532
1533
1534
1535
1536
1537







-
+


-
+


-
-
-







    Tcl_DStringAppend(dsPtr, " ", 1);
}

static void
SelCvtFromX8(
    char *propPtr,	/* Property value from X. */
    int numValues,		/* Number of 8-bit values in property. */
    Atom type,			/* Type of property Should not be XA_STRING
    TCL_UNUSED(Atom),			/* Type of property Should not be XA_STRING
				 * (if so, don't bother calling this function
				 * at all). */
    Tk_Window tkwin,		/* Window to use for atom conversion. */
    TCL_UNUSED(Tk_Window),		/* Window to use for atom conversion. */
    Tcl_DString *dsPtr)		/* Where to store the converted string. */
{
    (void)type;
    (void)tkwin;

    /*
     * Convert each long in the property to a string value, which is a
     * hexadecimal string. We build the list in a Tcl_DString because this is
     * easier than trying to get the quoting correct ourselves.
     */

    for ( ; numValues > 0; propPtr++, numValues--) {

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 © 1989-1994 The Regents of the University of California.
 * Copyright © 1994-1996 Sun Microsystems, Inc.
 * Copyright © 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"

939
940
941
942
943
944
945
946

947
948
949
950
951
952
953
939
940
941
942
943
944
945

946
947
948
949
950
951
952
953







-
+







 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_SendObjCmd(
    ClientData dummy,	/* Information about sender (only dispPtr
    TCL_UNUSED(void *),	/* Information about sender (only dispPtr
				 * field is used). */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    enum {
	SEND_ASYNC, SEND_DISPLAYOF, SEND_LAST
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
967
968
969
970
971
972
973

974
975
976
977
978
979
980







-







    Tcl_Time timeout;
    NameRegistry *regPtr;
    Tcl_DString request;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    Tcl_Interp *localInterp;	/* Used when the interpreter to send the
				 * command to is within the same process. */
    (void)dummy;

    /*
     * Process options, if any.
     */

    async = 0;
    winPtr = (TkWindow *) Tk_MainWindow(interp);
1353
1354
1355
1356
1357
1358
1359
1360

1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1352
1353
1354
1355
1356
1357
1358

1359
1360
1361
1362
1363
1364

1365
1366
1367
1368
1369
1370
1371







-
+





-







 *	Sets up various data structures and windows.
 *
 *--------------------------------------------------------------
 */

static int
SendInit(
    Tcl_Interp *dummy,		/* Interpreter to use for error reporting (no
    TCL_UNUSED(Tcl_Interp *),	/* Interpreter to use for error reporting (no
				 * errors are ever returned, but the
				 * interpreter is needed anyway). */
    TkDisplay *dispPtr)		/* Display to initialize. */
{
    XSetWindowAttributes atts;
    (void)dummy;

    /*
     * Create the window used for communication, and set up an event handler
     * for it.
     */

    dispPtr->commTkwin = (Tk_Window) TkAllocWindow(dispPtr,
1775
1776
1777
1778
1779
1780
1781
1782

1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1773
1774
1775
1776
1777
1778
1779

1780
1781
1782
1783
1784
1785

1786
1787
1788
1789
1790
1791
1792







-
+





-







 * The function below is invoked if an error occurs during the XChangeProperty
 * operation above.
 */

static int
AppendErrorProc(
    ClientData clientData,	/* Command to mark complete, or NULL. */
    XErrorEvent *errorPtr)	/* Information about error. */
    TCL_UNUSED(XErrorEvent *))	/* Information about error. */
{
    PendingCommand *pendingPtr = (PendingCommand *)clientData;
    PendingCommand *pcPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)errorPtr;

    if (pendingPtr == NULL) {
	return 0;
    }

    /*
     * Make sure this command is still pending.
1874
1875
1876
1877
1878
1879
1880
1881

1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1871
1872
1873
1874
1875
1876
1877

1878
1879
1880
1881

1882
1883
1884
1885
1886
1887
1888







-
+



-







 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tk_RestrictAction
SendRestrictProc(
    ClientData dummy,		/* Not used. */
    TCL_UNUSED(void *),		/* Not used. */
    XEvent *eventPtr)		/* Event that just arrived. */
{
    TkDisplay *dispPtr;
    (void)dummy;

    if (eventPtr->type != PropertyNotify) {
	return TK_DEFER_EVENT;
    }
    for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
	    dispPtr = dispPtr->nextPtr) {
	if ((eventPtr->xany.display == dispPtr->display)

Added unix/tkUnixSysNotify.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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
 * tkUnixSysNotify.c --
 *
 * 	tkUnixSysNotify.c implements a "sysnotify" Tcl command which
 * 	permits one to post system notifications based on the libnotify API.
 *
 * Copyright © 2020 Kevin Walzer/WordTech Communications LLC.
 * Copyright © 2020 Christian Werner for runtime linking
 *
 * 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 "tkUnixInt.h"

/*
 * Runtime linking of libnotify.
 */

typedef int	(*fn_ln_init)(const char *);
typedef void	(*fn_ln_uninit)(void);
typedef void *	(*fn_ln_notification_new)(const char *, const char *,
			const char *, void *);
typedef int	(*fn_ln_notification_show)(void *, int *);

static struct {
    int				nopen;
    Tcl_LoadHandle		lib;
    fn_ln_init			init;
    fn_ln_uninit		uninit;
    fn_ln_notification_new	notification_new;
    fn_ln_notification_show	notification_show;
} ln_fns = {
    0, NULL, NULL, NULL, NULL, NULL
};

#define notify_init			ln_fns.init
#define notify_uninit			ln_fns.uninit
#define notify_notification_new		ln_fns.notification_new
#define notify_notification_show	ln_fns.notification_show

TCL_DECLARE_MUTEX(ln_mutex);

/*
 * Forward declarations for procedures defined in this file.
 */

static void	SysNotifyDeleteCmd(void *);
static int	SysNotifyCmd(void *, Tcl_Interp *, int, Tcl_Obj * const*);

/*
 *----------------------------------------------------------------------
 *
 * SysNotifyDeleteCmd --
 *
 *      Delete notification and clean up.
 *
 * Results:
 *	Window destroyed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
SysNotifyDeleteCmd (
    TCL_UNUSED(void *))
{
    Tcl_MutexLock(&ln_mutex);
    if (--ln_fns.nopen == 0) {
	if (notify_uninit) {
	    notify_uninit();
	}
	if (ln_fns.lib != NULL) {
	    Tcl_FSUnloadFile(NULL, ln_fns.lib);
	}
	memset(&ln_fns, 0, sizeof(ln_fns));
    }
    Tcl_MutexUnlock(&ln_mutex);
}

/*
 *----------------------------------------------------------------------
 *
 * SysNotifyCreateCmd --
 *
 *      Create tray command and (unreal) window.
 *
 * Results:
 *	Icon tray and hidden window created.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
SysNotifyCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const *objv)
{
    const char *title;
    const char *message;
    const char *icon;
    void *notif;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "title message");
	return TCL_ERROR;
    }

    /*
     * Pass strings to notification, and use a sane platform-specific
     * icon in the alert.
     */

    title = Tcl_GetString(objv[1]);
    message = Tcl_GetString(objv[2]);
    icon = "dialog-information";

    /*
     * Call to notify_init should go here to prevent test suite failure.
     */

    if (notify_init && notify_notification_new && notify_notification_show) {
	Tcl_Encoding enc;
	Tcl_DString dst, dsm;

	enc = Tcl_GetEncoding(NULL, "utf-8");
	Tcl_ExternalToUtfDString(enc, title, -1, &dst);
	Tcl_ExternalToUtfDString(enc, message, -1, &dsm);
	notify_init("Wish");
	notif = notify_notification_new(title, message, icon, NULL);
	notify_notification_show(notif, NULL);
	Tcl_DStringFree(&dsm);
	Tcl_DStringFree(&dst);
	Tcl_FreeEncoding(enc);
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * SysNotify_Init --
 *
 *      Initialize the command.
 *
 * Results:
 *	Command initialized.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
SysNotify_Init(
    Tcl_Interp *interp)
{
    Tcl_MutexLock(&ln_mutex);
    if (ln_fns.nopen == 0) {
	int i = 0;
	Tcl_Obj *nameobj;
	static const char *lnlibs[] = {
	    "libnotify.so.4",
	    "libnotify.so.3",
	    "libnotify.so.2",
	    "libnotify.so.1",
	    "libnotify.so",
	    NULL
	};

	while (lnlibs[i] != NULL) {
	    Tcl_ResetResult(interp);
	    nameobj = Tcl_NewStringObj(lnlibs[i], -1);
	    Tcl_IncrRefCount(nameobj);
	    if (Tcl_LoadFile(interp, nameobj, NULL, 0, NULL, &ln_fns.lib)
		    == TCL_OK) {
		Tcl_DecrRefCount(nameobj);
		break;
	    }
	    Tcl_DecrRefCount(nameobj);
	    ++i;
	}
	if (ln_fns.lib != NULL) {
#define LN_SYM(name)							\
	    ln_fns.name = (fn_ln_ ## name)				\
		Tcl_FindSymbol(NULL, ln_fns.lib, "notify_" #name)
	    LN_SYM(init);
	    LN_SYM(uninit);
	    LN_SYM(notification_new);
	    LN_SYM(notification_show);
#undef LN_SYM
	}
    }
    ln_fns.nopen++;
    Tcl_MutexUnlock(&ln_mutex);

    Tcl_CreateObjCommand(interp, "::tk::sysnotify::_sysnotify", SysNotifyCmd,
	    interp, SysNotifyDeleteCmd);
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * coding: utf-8
 * End:
 */

Added unix/tkUnixSysTray.c.





























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
 * tkUnixSysTray.c --
 *
 * 	tkUnixSysTray.c implements a "systray" Tcl command which permits to
 * 	change the system tray/taskbar icon of a Tk toplevel window and
 * 	to post system notifications.
 *
 * Copyright © 2005 Anton Kovalenko.
 * Copyright © 2020 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 "tkInt.h"
#include "tkUnixInt.h"

/*
 * Based extensively on the tktray extension package. Here we are removing
 * non-essential parts of tktray.
 */

#include <time.h>
#include <string.h>
#include <stdio.h>

#include <X11/X.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>

/* XEmbed definitions
 * See http://www.freedesktop.org/wiki/Standards_2fxembed_2dspec
 * */
#define XEMBED_MAPPED           (1<<0)
/* System tray opcodes
 * See http://www.freedesktop.org/wiki/Standards_2fsystemtray_2dspec
 * */
#define SYSTEM_TRAY_REQUEST_DOCK    0
#define SYSTEM_TRAY_BEGIN_MESSAGE   1
#define SYSTEM_TRAY_CANCEL_MESSAGE  2

/* Flags of widget configuration options */
#define ICON_CONF_IMAGE         (1<<0)  /* Image changed */
#define ICON_CONF_REDISPLAY     (1<<1)  /* Redisplay required */
#define ICON_CONF_XEMBED        (1<<2)  /* Remapping or unmapping required */
#define ICON_CONF_CLASS         (1<<3)   /* TODO WM_CLASS update required */
#define ICON_CONF_FIRST_TIME    (1<<4)  /* For IconConfigureMethod invoked by the constructor */

/* Widget states */
#define ICON_FLAG_REDRAW_PENDING    (1<<0)
#define ICON_FLAG_ARGB32            (1<<1)
#define ICON_FLAG_DIRTY_EDGES       (1<<2)

#define TKU_NO_BAD_WINDOW_BEGIN(display) \
    { Tk_ErrorHandler error__handler = \
	    Tk_CreateErrorHandler(display, BadWindow, -1, -1, NULL, NULL);
#define TKU_NO_BAD_WINDOW_END Tk_DeleteErrorHandler(error__handler); }

/*Declaration for utility functions.*/
static void TKU_WmWithdraw(Tk_Window winPtr, Tcl_Interp* interp);
static Tk_Window TKU_GetWrapper(Tk_Window winPtr);
void TKU_AddInput(Display* dpy, Window win, long add_to_mask);
static Tk_Window TKU_Wrapper(Tk_Window w, Tcl_Interp* interp);
static Window TKU_XID(Tk_Window w);

/* Customized window withdraw */
static void
TKU_WmWithdraw(
    Tk_Window winPtr,
    TCL_UNUSED(Tcl_Interp *))
{
    TkpWmSetState((TkWindow*)winPtr, WithdrawnState);
}

/* The wrapper should exist */
static Tk_Window
TKU_GetWrapper(
    Tk_Window winPtr)
{
    return (Tk_Window)
	    TkpGetWrapperWindow((TkWindow*)winPtr);
}

/* Subscribe for extra X11 events (needed for MANAGER selection) */
void
TKU_AddInput(
    Display* dpy,
    Window win,
    long add_to_mask)
{
    XWindowAttributes xswa;
    TKU_NO_BAD_WINDOW_BEGIN(dpy)
        XGetWindowAttributes(dpy,win,&xswa);
        XSelectInput(dpy,win,xswa.your_event_mask|add_to_mask);
    TKU_NO_BAD_WINDOW_END
}

/* Get Tk Window wrapper (make it exist if ny) */
static Tk_Window
TKU_Wrapper(
    Tk_Window w,
    Tcl_Interp* interp)
{
    Tk_Window wrapper = TKU_GetWrapper(w);
    if (!wrapper) {
	Tk_MakeWindowExist(w);
	TKU_WmWithdraw(w, interp);
	Tk_MapWindow(w);
	wrapper = (Tk_Window) TKU_GetWrapper(w);
    }
    return wrapper;
}

/* Return X window id for Tk window (make it exist if ny) */
static Window
TKU_XID(
    Tk_Window w)
{
    Window xid = Tk_WindowId(w);
    if (xid == None) {
	Tk_MakeWindowExist(w);
	xid = Tk_WindowId(w);
    }
    return xid;
}

/* Data structure representing dock widget */
typedef struct {
    /* standard for widget */
    Tk_Window tkwin, drawingWin;
    Window wrapper;
    Window myManager;
    Window trayManager;

    Tk_OptionTable options;
    Tcl_Interp *interp;
    Tcl_Command widgetCmd;

    Tk_Image image; /* image to be drawn */

    /* Only one of imageVisualInstance and photo is needed for argb32
     * operations. Unless imageString changes, imageVisualInstance is
     * always valid for the same drawingWin instance, but photo is
     * invalidated by any "whole image" type change. */

    Tk_Image imageVisualInstance; /* image instance for use with argb32 */
    Tk_PhotoHandle photo;	  /* !null if it's really a photo */

    /* Offscreen pixmap is created for a given imageWidth,
     * imageHeight, drawingWin, and invalidated (and freed) on image
     * resize or drawingWin destruction.

     * Contents of this pixmap is synced on demand; when image changes
     * but is not resized, pixmap is marked as out-of-sync. Next time
     * when redisplay is needed, pixmap is updated before drawing
     * operation.
     */

    Pixmap offscreenPixmap;
    /* There is no need to recreate GC ever; it remains valid once
     * created */

    GC offscreenGC;

    /* XImage for drawing ARGB32 photo on offscreenPixmap.  Should be
     * freed and nullified each time when a pixmap is freed.  Needed
     * (and created) when redrawing an image being a photo on ARGB32
     * offscreen pixmap. */
    XImage *offscreenImage;	/* for photo (argb32) drawing code */

    Visual *bestVisual;		/* Visual, when it's specified by tray
				 * manager AND is guessed to be
				 * ARGB32 */
    Colormap bestColormap;	/* Colormap for bestVisual */

    Atom aMANAGER;
    Atom a_NET_SYSTEM_TRAY_Sn;
    Atom a_XEMBED_INFO;
    Atom a_NET_SYSTEM_TRAY_MESSAGE_DATA;
    Atom a_NET_SYSTEM_TRAY_OPCODE;
    Atom a_NET_SYSTEM_TRAY_ORIENTATION;
    Atom a_NET_SYSTEM_TRAY_VISUAL;

    int flags; /* ICON_FLAG_ - see defines above */
    int msgid; /* Last balloon message ID */
    int useShapeExt;

    int x,y,width,height;
    int imageWidth, imageHeight;
    int requestedWidth, requestedHeight;
    int visible; /* whether XEMBED_MAPPED should be set */
    int docked;	 /* whether an icon should be docked */
    char *imageString, /* option: -image as string */
	 *classString; /* option: -class as string */
} DockIcon;

/*
 * Forward declarations for procedures defined in this file.
 */

static int TrayIconCreateCmd(ClientData cd, Tcl_Interp *interp,
			     int objc,  Tcl_Obj *const objv[]);
static int TrayIconObjectCmd(ClientData cd, Tcl_Interp *interp,
			     int objc,  Tcl_Obj *const objv[]);
static int TrayIconConfigureMethod(DockIcon *icon, Tcl_Interp* interp,
				   int objc,  Tcl_Obj *const objv[],
				   int addflags);
static int PostBalloon(DockIcon* icon, const char * utf8msg,
		       long timeout);
static void CancelBalloon(DockIcon* icon, int msgid);
static int QueryTrayOrientation(DockIcon* icon);

static void TrayIconDeleteProc(ClientData cd );
static Atom DockSelectionAtomFor(Tk_Window tkwin);
static void DockToManager(DockIcon *icon);
static void CreateTrayIconWindow(DockIcon *icon);

static void TrayIconRequestSize(DockIcon* icon, int w, int h);
static void TrayIconForceImageChange(DockIcon* icon);
static void TrayIconUpdate(DockIcon* icon, int mask);

static void EventuallyRedrawIcon(DockIcon* icon);
static void DisplayIcon(ClientData cd);

static void RetargetEvent(DockIcon *icon, XEvent *ev);

static void TrayIconEvent(ClientData cd, XEvent* ev);
static void UserIconEvent(ClientData cd, XEvent* ev);
static void TrayIconWrapperEvent(ClientData cd, XEvent* ev);
static int IconGenericHandler(ClientData cd, XEvent *ev);

int Tktray_Init (Tcl_Interp* interp );

/*
 *----------------------------------------------------------------------
 *
 * TrayIconObjectCmd --
 *
 * 	Manage attributes of tray icon.
 *
 * Results:
 *	Various values of the tray icon are set and retrieved.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TrayIconObjectCmd(
    ClientData cd,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    DockIcon *icon = (DockIcon*)cd;
    int bbox[4] = {0,0,0,0};
    Tcl_Obj * bboxObj;
    int wcmd;
    int i;
    XWindowAttributes xwa;
    Window bogus;
    int msgid;

    enum {XWC_CONFIGURE = 0, XWC_CGET, XWC_BALLOON, XWC_CANCEL,
            XWC_BBOX, XWC_DOCKED, XWC_ORIENTATION};
    const char *st_wcmd[] = {"configure", "cget", "balloon", "cancel",
            "bbox", "docked", "orientation", NULL};

    long timeout = 0;
    Tcl_Obj* optionValue;

    if (objc<2) {
	Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], st_wcmd,
            "subcommand", TCL_EXACT, &wcmd) != TCL_OK) {
	return TCL_ERROR;
    }

    switch (wcmd) {
    case XWC_CONFIGURE:
	return TrayIconConfigureMethod(icon,interp,objc-2,objv+2,0);

    case XWC_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp,2,objv,"option");
	    return TCL_ERROR;
	}
	optionValue = Tk_GetOptionValue(interp,(char*)icon,
                icon->options,objv[2],icon->tkwin);
	if (optionValue) {
	    Tcl_SetObjResult(interp,optionValue);
	    return TCL_OK;
	} else {
	    return TCL_ERROR;
	}

    case XWC_BALLOON:
	if ((objc != 3) && (objc != 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "message ?timeout?");
	    return TCL_ERROR;
	}
	if (objc == 4) {
	    if (Tcl_GetLongFromObj(interp,objv[3],&timeout) != TCL_OK)
		return TCL_ERROR;
	}
	msgid = PostBalloon(icon,Tcl_GetString(objv[2]), timeout);
	Tcl_SetObjResult(interp,Tcl_NewIntObj(msgid));
	return TCL_OK;

    case XWC_CANCEL:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "messageId");
	    return TCL_ERROR;
	}
	if (Tcl_GetIntFromObj(interp,objv[2],&msgid) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (msgid)
	    CancelBalloon(icon,msgid);
	return TCL_OK;

    case XWC_BBOX:
	if (icon->drawingWin) {
	    XGetWindowAttributes(Tk_Display(icon->drawingWin),
                    TKU_XID(icon->drawingWin), &xwa);

	    XTranslateCoordinates(Tk_Display(icon->drawingWin),
                    TKU_XID(icon->drawingWin), xwa.root, 0,0,
                    &icon->x, &icon->y, &bogus);
	    bbox[0] = icon->x;
	    bbox[1] = icon->y;
	    bbox[2] = bbox[0] + icon->width - 1;
	    bbox[3] = bbox[1] + icon->height - 1;
	}
	bboxObj = Tcl_NewObj();
	for (i = 0; i < 4; ++i) {
	    Tcl_ListObjAppendElement(interp, bboxObj, Tcl_NewIntObj(bbox[i]));
	}
	Tcl_SetObjResult(interp, bboxObj);
	return TCL_OK;

    case XWC_DOCKED:
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(icon->myManager != None));
	return TCL_OK;

    case XWC_ORIENTATION:
	if (icon->myManager == None || icon->wrapper == None) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("none", -1));
	} else {
	    switch(QueryTrayOrientation(icon)) {
	    case 0:
		Tcl_SetObjResult(interp, Tcl_NewStringObj("horizontal", -1));
		break;
	    case 1:
		Tcl_SetObjResult(interp, Tcl_NewStringObj("vertical", -1));
		break;
	    default:
		Tcl_SetObjResult(interp, Tcl_NewStringObj("unknown", -1));
		break;
	    }
	}
	return TCL_OK;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * QueryTrayOrientation --
 *
 * 	Obtain the orientation of the tray icon.
 *
 * Results:
 *	Orientation is returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
QueryTrayOrientation(
    DockIcon* icon)
{
    Atom retType = None;
    int retFormat = 32;
    unsigned long retNitems, retBytesAfter;
    unsigned char *retProp = NULL;
    int result = -1;

    if (icon->wrapper != None && icon->myManager != None) {
	XGetWindowProperty(Tk_Display(icon->tkwin),
			   icon->myManager,
			   icon->a_NET_SYSTEM_TRAY_ORIENTATION,
			   /* offset */ 0,
			   /* length */ 1,
			   /* delete */ False,
			   /* type */ XA_CARDINAL,
			   &retType, &retFormat, &retNitems,
			   &retBytesAfter, &retProp);
	if (retType == XA_CARDINAL && retFormat == 32 && retNitems == 1) {
	    result = (int) *(long*)retProp;
	}
	if (retProp) {
	    XFree(retProp);
	}
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * DockSelectionAtomFor --
 *
 * 	Obtain the dock selection atom.
 *
 * Results:
 *	Selection returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Atom
DockSelectionAtomFor(
    Tk_Window tkwin)
{
    char buf[256];
    /* no snprintf in C89 */
    sprintf(buf,"_NET_SYSTEM_TRAY_S%d",Tk_ScreenNumber(tkwin));
    return Tk_InternAtom(tkwin,buf);
}

/*
 *----------------------------------------------------------------------
 *
 * XembedSetState --
 *
 * 	Set the xembed state.
 *
 * Results:
 *	Updates the xembed state.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
XembedSetState(
    DockIcon *icon,
    long xembedState)
{
    long info[] = { 0, 0 };
    info[1] = xembedState;
    if (icon->drawingWin) {
	XChangeProperty(Tk_Display(icon->drawingWin),
			icon->wrapper,
			icon->a_XEMBED_INFO,
			icon->a_XEMBED_INFO, 32,
			PropModeReplace, (unsigned char*)info, 2);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * XembedRequestDock --
 *
 * 	Obtain the docking window.
 *
 * Results:
 *	The dock window is requested.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
XembedRequestDock(
    DockIcon *icon)
{
    Tk_Window tkwin = icon->drawingWin;
    XEvent ev;
    Display *dpy = Tk_Display(tkwin);

    memset(&ev, 0, sizeof(ev));
    ev.xclient.type = ClientMessage;
    ev.xclient.window = icon->myManager;
    ev.xclient.message_type = icon->a_NET_SYSTEM_TRAY_OPCODE;
    ev.xclient.format = 32;
    ev.xclient.data.l[0] = 0;
    ev.xclient.data.l[1] = SYSTEM_TRAY_REQUEST_DOCK;
    ev.xclient.data.l[2] = icon->wrapper;
    ev.xclient.data.l[3] = 0;
    ev.xclient.data.l[4] = 0;
    XSendEvent(dpy, icon->myManager, True, StructureNotifyMask|SubstructureNotifyMask, &ev);
 }

/*
 *----------------------------------------------------------------------
 *
 * CheckArgbVisual --
 *
 * 	Find out if a visual is recommended and if it looks like argb32.
 *
 * Results:
 *	Render the visual as needed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
CheckArgbVisual(
    DockIcon *icon)
{
    /* Find out if a visual is recommended and if it looks like argb32.
     * For such visuals we should:
     * Recreate a window if it's created but the depth is wrong;
     * Don't use ParentRelative but blank background.
     * For photo images, draw into a window by XPutImage.
     */
    Atom retType = None;
    int retFormat = 32;
    unsigned long retNitems, retBytesAfter;
    unsigned char *retProp = NULL;
    Visual *match = NULL;
    int depth = 0;
    Colormap cmap = None;

    TKU_NO_BAD_WINDOW_BEGIN(Tk_Display(icon->tkwin))
        XGetWindowProperty(Tk_Display(icon->tkwin),
                icon->trayManager,
                icon->a_NET_SYSTEM_TRAY_VISUAL,
                /* offset */ 0,
                /* length */ 1,
                /* delete */ False,
                /* type */ XA_VISUALID,
                &retType, &retFormat, &retNitems,
                &retBytesAfter, &retProp);
    TKU_NO_BAD_WINDOW_END
    if (retType == XA_VISUALID &&
	    retNitems == 1 &&
	    retFormat == 32) {
	char numeric[256];
	sprintf(numeric,"%ld",*(long*)retProp);
	XFree(retProp);
	match = Tk_GetVisual(icon->interp, icon->tkwin,
                numeric, &depth, &cmap);
    }
    if (match&& depth == 32 &&
	    match->red_mask == 0xFF0000UL &&
	    match->green_mask == 0x00FF00UL &&
	    match->blue_mask == 0x0000FFUL) {
	icon->bestVisual = match;
	icon->bestColormap = cmap;
    } else {
	icon->bestVisual = NULL;
	icon->bestColormap = None;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * CreateTrayIconWindow --
 *
 * 	Create and configure the window for the icon tray.
 *
 * Results:
 *	The window is created and displayed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
CreateTrayIconWindow(
    DockIcon *icon)
{
    Tcl_SavedResult oldResult;
    Tk_Window tkwin;
    Tk_Window wrapper;
    XSetWindowAttributes attr;

    Tcl_SaveResult(icon->interp, &oldResult);
    /* Use the same name (tail) as the widget name, to enable
     * name-based icon management for supporting trays, as promised by
     * the docs.
     */
    tkwin = icon->drawingWin = Tk_CreateWindow(icon->interp, icon->tkwin,
            Tk_Name(icon->tkwin), "");
    if (tkwin) {
	Tk_SetClass(icon->drawingWin,icon->classString);
	Tk_CreateEventHandler(icon->drawingWin,ExposureMask|StructureNotifyMask|
                ButtonPressMask|ButtonReleaseMask|
                EnterWindowMask|LeaveWindowMask|PointerMotionMask,
                TrayIconEvent,(ClientData)icon);
	if(icon->bestVisual) {
	    Tk_SetWindowVisual(icon->drawingWin,icon->bestVisual,
                    32,icon->bestColormap);
	    icon->flags |= ICON_FLAG_ARGB32;
	    Tk_SetWindowBackground(tkwin, 0);
	} else {
	    Tk_SetWindowBackgroundPixmap(tkwin, ParentRelative);
	    icon->flags &= ~ICON_FLAG_ARGB32;
	}
	Tk_MakeWindowExist(tkwin);
	TKU_WmWithdraw(tkwin,icon->interp);
	wrapper = TKU_Wrapper(tkwin,icon->interp);

	attr.override_redirect = True;
	Tk_ChangeWindowAttributes(wrapper,CWOverrideRedirect,&attr);
	Tk_CreateEventHandler(wrapper,StructureNotifyMask,TrayIconWrapperEvent,(ClientData)icon);
	if (!icon->bestVisual) {
	    Tk_SetWindowBackgroundPixmap(wrapper, ParentRelative);
	} else {
	    Tk_SetWindowBackground(tkwin, 0);
	}
	icon->wrapper = TKU_XID(wrapper);
	TrayIconForceImageChange(icon);
    } else {
	Tcl_BackgroundError(icon->interp);
    }
    Tcl_RestoreResult(icon->interp, &oldResult);
}

/*
 *----------------------------------------------------------------------
 *
 * DockToManager --
 *
 * 	Helper function to manage icon in display.
 *
 * Results:
 *	Icon is created and displayed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
DockToManager(
    DockIcon *icon)
{
    icon->myManager = icon->trayManager;
    Tk_SendVirtualEvent(icon->tkwin,Tk_GetUid("IconCreate"), NULL);
    XembedSetState(icon, icon->visible ? XEMBED_MAPPED : 0);
    XembedRequestDock(icon);
}

static const
Tk_OptionSpec IconOptionSpec[] = {
    {TK_OPTION_STRING,"-image","image","Image",
        (char *) NULL, -1, offsetof(DockIcon, imageString),
        TK_OPTION_NULL_OK, NULL,
        ICON_CONF_IMAGE | ICON_CONF_REDISPLAY},
    {TK_OPTION_STRING,"-class","class","Class",
        "TrayIcon", -1, offsetof(DockIcon, classString),
        0, NULL, ICON_CONF_CLASS},
    {TK_OPTION_BOOLEAN,"-docked","docked","Docked",
        "1", -1, offsetof(DockIcon, docked), 0, NULL,
        ICON_CONF_XEMBED | ICON_CONF_REDISPLAY},
    {TK_OPTION_BOOLEAN,"-shape","shape","Shape",
        "0", -1, offsetof(DockIcon, useShapeExt), 0, NULL,
        ICON_CONF_IMAGE | ICON_CONF_REDISPLAY},
    {TK_OPTION_BOOLEAN,"-visible","visible","Visible",
        "1", -1, offsetof(DockIcon, visible), 0, NULL,
        ICON_CONF_XEMBED | ICON_CONF_REDISPLAY},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

/*
 *----------------------------------------------------------------------
 *
 * TrayIconRequestSize --
 *
 * 	Set icon size.
 *
 * Results:
 *	Icon size is obtained/set.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
TrayIconRequestSize(
    DockIcon* icon,
    int w,
    int h)
{
    if (icon->drawingWin) {
	if (icon->requestedWidth != w ||
	        icon->requestedHeight != h) {
	    Tk_SetMinimumRequestSize(icon->drawingWin,w,h);
	    Tk_GeometryRequest(icon->drawingWin,w,h);
	    Tk_SetGrid(icon->drawingWin,1,1,w,h);
	    icon->requestedWidth = w;
	    icon->requestedHeight = h;
	}
    } else {
	/* Sign that no size is requested yet */
	icon->requestedWidth = 0;
	icon->requestedHeight = 0;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TrayIconImageChanged --
 *
 * 	Fires when icon state changes.
 *
 * Results:
 *	Icon changes are rendered.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
TrayIconImageChanged(
    ClientData cd,
    int x,
    int y,
    int w,
    int h,
    int imgw,
    int imgh)
{
    DockIcon *icon = (DockIcon*) cd;
    if (imgw != icon->imageWidth || imgh != icon->imageHeight) {
	if (icon->offscreenImage) {
	    XDestroyImage(icon->offscreenImage);
	    icon->offscreenImage = NULL;
	}
	if (icon->offscreenPixmap) {
	    /* its size is bad */
	    Tk_FreePixmap(Tk_Display(icon->tkwin), icon->offscreenPixmap);
	    icon->offscreenPixmap = None;
	}
	/* if some image dimension decreases,
	 * empty areas around the image should be cleared */
	if (imgw < icon->imageWidth || imgh < icon->imageHeight) {
	    icon->flags |= ICON_FLAG_DIRTY_EDGES;
	}
    }
    icon->imageWidth = imgw;
    icon->imageHeight = imgh;
    if (imgw == w && imgh == h && x == 0 && y == 0) {
	icon->photo = NULL;	/* invalidate */
    }
    TrayIconRequestSize(icon,imgw,imgh);
    EventuallyRedrawIcon(icon);
}

/*
 *----------------------------------------------------------------------
 *
 * IgnoreImageChange --
 *
 * 	Currently no-op.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
IgnoreImageChange(
    TCL_UNUSED(void *),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{
}

/*
 *----------------------------------------------------------------------
 *
 * ForceImageChange --
 *
 * 	Push icon changes through.
 *
 * Results:
 *	Icon image is updated.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
TrayIconForceImageChange(
    DockIcon* icon)
{
    if (icon->image) {
	int w,h;
	Tk_SizeOfImage(icon->image,&w,&h);
	TrayIconImageChanged((ClientData)icon,0,0,w,h,w,h);
    }
}

/*
 *----------------------------------------------------------------------
 *
 *  EventuallyRedrawIcon --
 *
 * 	Update image icon.
 *
 * Results:
 *	Icon image is updated.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
EventuallyRedrawIcon(
    DockIcon* icon)
{
    if (icon->drawingWin && icon->myManager) {	/* don't redraw invisible icon */
	if (!(icon->flags & ICON_FLAG_REDRAW_PENDING)) { /* don't schedule multiple redraw ops */
	    icon->flags |= ICON_FLAG_REDRAW_PENDING;
	    Tcl_DoWhenIdle(DisplayIcon,(ClientData)icon);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 *  DisplayIcon --
 *
 * 	Main function for displaying icon.
 *
 * Results:
 *	Icon image is displayed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
DisplayIcon(
    ClientData cd)
{
    DockIcon *icon = (DockIcon*)cd;
    int w = icon->imageWidth, h = icon->imageHeight;
    int imgx, imgy, outx, outy, outw, outh;
    imgx = (icon->width >= w) ? 0 : -(icon->width - w)/2;
    imgy = (icon->height >= h) ? 0 : -(icon->height - h)/2;
    outx = (icon->width >= w) ? (icon->width - w)/2 : 0;
    outy = (icon->height >= h) ? (icon->height - h)/2 : 0;
    outw = (icon->width >= w) ? w : icon->width;
    outh = (icon->height >= h) ? h : icon->height;

    icon->flags &= (~ICON_FLAG_REDRAW_PENDING);

    if (icon->drawingWin && icon->docked) {
	if (icon->flags & ICON_FLAG_ARGB32) {
	    /* ARGB32 redraw: never use a ParentRelative method, and
	       no need to clear window except FIXME when its size changed.
	       Draw on the offscreen pixmap instead, then copy to the window.
	     */
	    if (icon->offscreenPixmap == None) {
		icon->offscreenPixmap = Tk_GetPixmap(Tk_Display(icon->drawingWin),
                        Tk_WindowId(icon->drawingWin), w, h, 32);
	    }
	    if (!icon->photo) {
		icon->photo = Tk_FindPhoto(icon->interp, icon->imageString);
	    }
	    if (!icon->photo && !icon->imageVisualInstance) {
		Tcl_SavedResult saved;
		Tcl_SaveResult(icon->interp,&saved);
		icon->imageVisualInstance = Tk_GetImage(icon->interp,icon->drawingWin,
                        icon->imageString, IgnoreImageChange,(ClientData)NULL);
		Tcl_RestoreResult(icon->interp,&saved);
	    }
	    if (icon->photo && !icon->offscreenImage) {
		icon->offscreenImage = XGetImage(Tk_Display(icon->drawingWin),
                        icon->offscreenPixmap, 0, 0, w, h, AllPlanes, ZPixmap);
	    }
	    if (icon->offscreenGC == None) {
		XGCValues gcv;
		gcv.function = GXcopy;
		gcv.plane_mask = AllPlanes;
		gcv.foreground = 0;
		gcv.background = 0;
		icon->offscreenGC = Tk_GetGC(icon->drawingWin,
                        GCFunction|GCPlaneMask|GCForeground|GCBackground, &gcv);
	    }
	    if (icon->flags & ICON_FLAG_DIRTY_EDGES) {
		XClearWindow(Tk_Display(icon->drawingWin), TKU_XID(icon->drawingWin));
		icon->flags &= ~ICON_FLAG_DIRTY_EDGES;
	    }
	    if (icon->photo) {
		Tk_PhotoImageBlock pib;
		int cx,cy;
		XImage *xim = icon->offscreenImage;
		/* redraw photo using raw data */
		Tk_PhotoGetImage(icon->photo,&pib);
		for (cy = 0; cy < h; ++cy) {
		    for (cx = 0; cx < w; ++cx) {
			XPutPixel(xim,cx,cy,
				  (*(pib.pixelPtr +
				     pib.pixelSize*cx +
				     pib.pitch*cy +
				     pib.offset[0])<<16) |
				  (*(pib.pixelPtr +
				     pib.pixelSize*cx +
				     pib.pitch*cy +
				     pib.offset[1])<<8) |
				  (*(pib.pixelPtr +
				     pib.pixelSize*cx +
				     pib.pitch*cy +
				     pib.offset[2])) |
				  (pib.offset[3] ?
				   (*(pib.pixelPtr +
				      pib.pixelSize*cx +
				      pib.pitch*cy +
				      pib.offset[3])<<24) : 0));
		    }
		}
		XPutImage(Tk_Display(icon->drawingWin),
			icon->offscreenPixmap,
			icon->offscreenGC,
			icon->offscreenImage,
			0,0,0,0,w,h);
	    } else {
		XFillRectangle(Tk_Display(icon->drawingWin),
			icon->offscreenPixmap,
			icon->offscreenGC,
			0,0,w,h);
		if (icon->imageVisualInstance) {
		    Tk_RedrawImage(icon->imageVisualInstance,
                            0,0,w,h,
                            icon->offscreenPixmap,
                            0,0);
		}
	    }
	    XCopyArea(Tk_Display(icon->drawingWin),
                    icon->offscreenPixmap,
                    TKU_XID(icon->drawingWin),
                    icon->offscreenGC,
                    imgx,imgy,outw,outh,outx,outy);
	} else {
	    /* Non-argb redraw: clear window and draw an image over it.
	       For photos it gives a correct alpha blending with a parent
	       window background, even if it's a fancy pixmap (proved to
	       work with lxpanel fancy backgrounds).
	    */
	    XClearWindow(Tk_Display(icon->drawingWin),
                    TKU_XID(icon->drawingWin));
	    if (icon->image && icon->visible) {
		Tk_RedrawImage(icon->image,imgx,imgy,outw,outh,
                        TKU_XID(icon->drawingWin), outx, outy);
	    }
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 *  RetargetEvent --
 *
 * 	Redirect X events to widgets.
 *
 * Results:
 *	Icon image is displayed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
RetargetEvent(
    DockIcon *icon,
    XEvent *ev)
{
    int send = 0;
    Window* saveWin1 = NULL, *saveWin2 = NULL;
    if (!icon->visible)
	return;
    switch (ev->type) {
    case MotionNotify:
	send = 1;
	saveWin1 = &ev->xmotion.subwindow;
	saveWin2 = &ev->xmotion.window;
	break;
    case LeaveNotify:
    case EnterNotify:
	send = 1;
	saveWin1 = &ev->xcrossing.subwindow;
	saveWin2 = &ev->xcrossing.window;
	break;
    case ButtonPress:
    case ButtonRelease:
	send = 1;
	saveWin1 = &ev->xbutton.subwindow;
	saveWin2 = &ev->xbutton.window;
	break;
    case MappingNotify:
	send = 1;
	saveWin1 = &ev->xmapping.window;
    }
    if (saveWin1) {
	Tk_MakeWindowExist(icon->tkwin);
	*saveWin1 = Tk_WindowId(icon->tkwin);
	if (saveWin2) *saveWin2 = *saveWin1;
    }
    if (send) {
	ev->xany.send_event = 0x147321ac;
	Tk_HandleEvent(ev);
    }
}

/*
 *----------------------------------------------------------------------
 *
 *  TrayIconWrapperEvent --
 *
 * 	Ensure automapping in root window is done in withdrawn state.
 *
 * Results:
 *	Icon image is displayed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
TrayIconWrapperEvent(
    ClientData cd,
    XEvent* ev)
{
  /* Some embedders, like Docker, add icon windows to save set
   * (XAddToSaveSet), so when they crash the icon is reparented to root.
   * We have to make sure that automatic mapping in root is done in
   * withdrawn state (no way to prevent it entirely)
   */
    DockIcon *icon = (DockIcon*)cd;
    XWindowAttributes attr;
    if (icon->drawingWin) {
	switch(ev->type) {
	case ReparentNotify:
	    /* With virtual roots and screen roots etc, the only way
	       to check for reparent-to-root is to ask for this root
	       first */
	    XGetWindowAttributes(ev->xreparent.display,
                    ev->xreparent.window, &attr);
	    if (attr.root == ev->xreparent.parent) {
		/* upon reparent to root, */
		if (icon->drawingWin) {
		    /* we were sent away to root */
		    TKU_WmWithdraw(icon->drawingWin,icon->interp);
		    if (icon->myManager)
			Tk_SendVirtualEvent(icon->tkwin,Tk_GetUid("IconDestroy"), NULL);
		    icon->myManager = None;
		}
	    } /* Reparenting into some other embedder is theoretically possible,
	       * and everything would just work in this case.
               */
	    break;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TrayIconEvent --
 *
 * 	Handle X events.
 *
 * Results:
 *	Events are handled and processed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
TrayIconEvent(
    ClientData cd,
    XEvent* ev)
{
    DockIcon *icon = (DockIcon*)cd;

    switch (ev->type) {
    case Expose:
	if (!ev->xexpose.count)
	    EventuallyRedrawIcon(icon);
	break;

    case DestroyNotify:
	/* If anonymous window is destroyed first, then either
	 * something went wrong with a tray (if -visible) or we just
	 * reconfigured to invisibility: nothing to be done in both
	 * cases.
	 * If unreal window is destroyed first, freeing the data structures
	 * is the only thing to do.
	 */
	if (icon->myManager) {
	    Tk_SendVirtualEvent(icon->tkwin,Tk_GetUid("IconDestroy"), NULL);
	}
	Tcl_CancelIdleCall(DisplayIcon,(ClientData)icon);
	icon->flags &= ~ICON_FLAG_REDRAW_PENDING;
	icon->drawingWin = NULL;
	icon->requestedWidth = 0; /* trigger re-request on recreation */
	icon->requestedHeight = 0;
	icon->wrapper = None;
	icon->myManager = None;
	break;

    case ConfigureNotify:
	Tk_SendVirtualEvent(icon->tkwin,Tk_GetUid("IconConfigure"), NULL);
	if (icon->width != ev->xconfigure.width ||
	        icon->height != ev->xconfigure.height) {
	    icon->width = ev->xconfigure.width;
	    icon->height = ev->xconfigure.height;
	    icon->flags |= ICON_FLAG_DIRTY_EDGES;
	    EventuallyRedrawIcon(icon);
	}
	RetargetEvent(icon,ev);
	break;

    case MotionNotify:  /* fall through */
    case ButtonPress:   /* fall through */
    case ButtonRelease: /* fall through */
    case EnterNotify:   /* fall through */
    case LeaveNotify:
	RetargetEvent(icon,ev);
	break;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * UserIconEvent --
 *
 * 	Handle user events.
 *
 * Results:
 *	Events are handled and processed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
UserIconEvent(
    ClientData cd,
    XEvent* ev)
{
    DockIcon *icon = (DockIcon*)cd;

    switch (ev->type) {

    case DestroyNotify:
	Tk_DeleteGenericHandler(IconGenericHandler, (ClientData)icon);
	if(icon->drawingWin) {
	    icon->visible = 0;
	    Tcl_CancelIdleCall(DisplayIcon,(ClientData)icon);
	    icon->flags &= ~ICON_FLAG_REDRAW_PENDING;
	    Tk_DestroyWindow(icon->drawingWin);
	}
	if(icon->imageVisualInstance) {
	    Tk_FreeImage(icon->imageVisualInstance);
	    icon->image = NULL;
	}
	if(icon->offscreenImage) {
	    XDestroyImage(icon->offscreenImage);
	    icon->offscreenImage = NULL;
	}
	if(icon->offscreenGC) {
	    Tk_FreeGC(Tk_Display(icon->tkwin),icon->offscreenGC);
	    icon->offscreenGC = NULL;
	}
	if(icon->offscreenPixmap) {
	    Tk_FreePixmap(Tk_Display(icon->tkwin),icon->offscreenPixmap);
	}
	if(icon->image) {
	    Tk_FreeImage(icon->image);
	    icon->image = NULL;
	}
	if(icon->widgetCmd)
	    Tcl_DeleteCommandFromToken(icon->interp,icon->widgetCmd);
	Tk_FreeConfigOptions((char*)icon, icon->options, icon->tkwin);
	break;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * PostBalloon --
 *
 * 	Display tooltip/balloon window over tray icon.
 *
 * Results:
 *	Window is displayed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
PostBalloon(
    DockIcon *icon,
    const char *utf8msg,
    long timeout)
{
    Tk_Window tkwin = icon -> tkwin;
    Display* dpy = Tk_Display(tkwin);
    int length = strlen(utf8msg);
    XEvent ev;

    if (!(icon->drawingWin) || (icon->myManager == None))
	return 0;

    /* overflow protection */
    if (icon->msgid < 0)
	icon->msgid = 0;

    memset(&ev, 0, sizeof(ev));
    ev.xclient.type = ClientMessage;
    ev.xclient.window = icon->wrapper;
    ev.xclient.message_type = icon->a_NET_SYSTEM_TRAY_OPCODE;
    ev.xclient.format = 32;
    ev.xclient.data.l[0] = CurrentTime;
    ev.xclient.data.l[1] = SYSTEM_TRAY_BEGIN_MESSAGE;
    ev.xclient.data.l[2] = timeout;
    ev.xclient.data.l[3] = length;
    ev.xclient.data.l[4] = ++icon->msgid;
    TKU_NO_BAD_WINDOW_BEGIN(Tk_Display(icon->tkwin))
	XSendEvent(dpy, icon->myManager , True, StructureNotifyMask|SubstructureNotifyMask, &ev);
        XSync(dpy, False);

        /* Sending message elements */
        while (length>0) {
	    ev.type = ClientMessage;
	    ev.xclient.window = icon->wrapper;
	    ev.xclient.message_type = icon->a_NET_SYSTEM_TRAY_MESSAGE_DATA;
	    ev.xclient.format = 8;
	    memset(ev.xclient.data.b,0,20);
	    strncpy(ev.xclient.data.b,utf8msg,length<20?length:20);
	    XSendEvent(dpy, icon->myManager, True, StructureNotifyMask|SubstructureNotifyMask, &ev);
	    XSync(dpy,False);
	    utf8msg += 20;
	    length -= 20;
        }
    TKU_NO_BAD_WINDOW_END;
    return icon->msgid;
}

/*
 *----------------------------------------------------------------------
 *
 * CancelBalloon --
 *
 * 	Remove balloon from display over tray icon.
 *
 * Results:
 *	Window is destroyed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
CancelBalloon(
    DockIcon *icon,
    int msgid)
{
    Tk_Window tkwin = icon -> tkwin;
    Display* dpy = Tk_Display(tkwin);
    XEvent ev;

    if (!(icon->drawingWin) || (icon->myManager == None))
	return;
    /* overflow protection */
    if (icon->msgid < 0)
	icon->msgid = 0;

    memset(&ev, 0, sizeof(ev));
    ev.type = ClientMessage;
    ev.xclient.window = icon->wrapper;
    ev.xclient.message_type = icon->a_NET_SYSTEM_TRAY_OPCODE;
    ev.xclient.format = 32;
    ev.xclient.data.l[0] = CurrentTime;
    ev.xclient.data.l[1] = SYSTEM_TRAY_CANCEL_MESSAGE;
    ev.xclient.data.l[2]  =msgid;
    TKU_NO_BAD_WINDOW_BEGIN(Tk_Display(icon->tkwin))
	XSendEvent(dpy, icon->myManager , True,
                StructureNotifyMask|SubstructureNotifyMask, &ev);
    TKU_NO_BAD_WINDOW_END
}

/*
 *----------------------------------------------------------------------
 *
 * IconGenericHandler --
 *
 * 	Process non-tk events.
 *
 * Results:
 *	Events are processed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
IconGenericHandler(
    ClientData cd,
    XEvent *ev)
{
    DockIcon *icon = (DockIcon*)cd;

    if ((ev->type == ClientMessage) &&
	    (ev->xclient.message_type == icon->aMANAGER) &&
	    ((Atom)ev->xclient.data.l[1] == icon->a_NET_SYSTEM_TRAY_Sn)) {
	icon->trayManager = (Window)ev->xclient.data.l[2];
	XSelectInput(ev->xclient.display,icon->trayManager,StructureNotifyMask);
	if (icon->myManager == None)
	    TrayIconUpdate(icon, ICON_CONF_XEMBED);
	return 1;
    }
    if (ev->type == DestroyNotify) {
	if (ev->xdestroywindow.window == icon->trayManager) {
	    icon->trayManager = None;
	}
	if (ev->xdestroywindow.window == icon->myManager) {
	    icon->myManager = None;
	    icon->wrapper = None;
	    if (icon->drawingWin) {
		Tk_DestroyWindow(icon->drawingWin);
		icon->drawingWin = NULL;
	    }
	}
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TrayIconUpdate --
 *
 * 	Get in touch with new options that are certainly valid.
 *
 * Results:
 *	Options updated.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
TrayIconUpdate(
    DockIcon *icon,
    int mask)
{
    /* why should someone need this option?
     * anyway, let's handle it if we provide it.
     */
    if (mask & ICON_CONF_CLASS) {
	if (icon->drawingWin)
	    Tk_SetClass(icon->drawingWin,Tk_GetUid(icon->classString));
    }
    /*
     * First, ensure right icon visibility.
     * If should be visible and not yet managed,
     * we have to get the tray or wait for it.
     * If should be invisible and managed,
     * real-window is simply destroyed.
     * If should be invisible and not managed,
     * generic handler should be abandoned.
     */
    if (mask & ICON_CONF_XEMBED) {
	if (icon->myManager == None &&
	        icon->trayManager != None &&
	        icon->docked) {
	    CheckArgbVisual(icon);
	    if (icon->drawingWin &&
		    ((icon->bestVisual && !(icon->flags & ICON_FLAG_ARGB32)) ||
		     (!icon->bestVisual && (icon->flags & ICON_FLAG_ARGB32)))) {
		icon->myManager = None;
		icon->wrapper = None;
		icon->requestedWidth = icon->requestedHeight = 0;
		Tk_DestroyWindow(icon->drawingWin);
		icon->drawingWin = NULL;
	    }
	    if (!icon->drawingWin) {
		CreateTrayIconWindow(icon);
	    }
	    if (icon->drawingWin) {
		DockToManager(icon);
	    }
	}
	if (icon->myManager != None &&
	        icon->drawingWin != NULL &&
	        !icon->docked) {
	    Tk_DestroyWindow(icon->drawingWin);
	    icon->drawingWin = NULL;
	    icon->myManager = None;
	    icon->wrapper = None;
	}
	if (icon->drawingWin) {
	    XembedSetState(icon, icon->visible ? XEMBED_MAPPED : 0);
	}
    }
    if (mask & ICON_CONF_IMAGE) {
	TrayIconForceImageChange(icon);
    }
    if (mask & ICON_CONF_REDISPLAY) {
	EventuallyRedrawIcon(icon);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TrayIconConfigureMethod --
 *
 *      Returns TCL_ERROR if some option is invalid,
 *      or else retrieve resource references and free old resources.
 *
 * Results:
 *	Widget configured.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TrayIconConfigureMethod(
    DockIcon *icon,
    Tcl_Interp* interp,
    int objc,
    Tcl_Obj *const objv[],
    int addflags)
{
    Tk_SavedOptions saved;
    Tk_Image newImage = NULL;
    int mask = 0;

    if (objc <= 1 && !(addflags & ICON_CONF_FIRST_TIME)) {
	Tcl_Obj* info = Tk_GetOptionInfo(interp, (char*)icon, icon->options,
                objc? objv[0] : NULL, icon->tkwin);
	if (info) {
	    Tcl_SetObjResult(interp,info);
	    return TCL_OK;
	} else {
	    return TCL_ERROR; /* msg by Tk_GetOptionInfo */
	}
    }

    if (Tk_SetOptions(interp,(char*)icon,icon->options,objc,objv,
            icon->tkwin,&saved,&mask) != TCL_OK) {
	return TCL_ERROR; /* msg by Tk_SetOptions */
    }
    mask |= addflags;
    /* now check option validity */
    if (mask & ICON_CONF_IMAGE) {
	if (icon->imageString) {
	    newImage = Tk_GetImage(interp, icon->tkwin, icon->imageString,
                    TrayIconImageChanged, (ClientData)icon);
	    if (!newImage) {
		Tk_RestoreSavedOptions(&saved);
		return TCL_ERROR; /* msg by Tk_GetImage */
	    }
	}
	if (icon->image) {
	    Tk_FreeImage(icon->image);
	    icon->image = NULL;
	}
	if (icon->imageVisualInstance) {
	    Tk_FreeImage(icon->imageVisualInstance);
	    icon->imageVisualInstance = NULL;
	}
	icon->image = newImage; /* may be null, as intended */
	icon->photo = NULL; /* invalidate photo reference */
    }
    Tk_FreeSavedOptions(&saved);
    /* Now as we are reconfigured... */
    TrayIconUpdate(icon,mask);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TrayIconDeleteProc --
 *
 *      Delete tray window and clean up.
 *
 * Results:
 *	Window destroyed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
TrayIconDeleteProc(
    ClientData cd )
{
    DockIcon *icon = (DockIcon *)cd;
    Tk_DestroyWindow(icon->tkwin);
}

/*
 *----------------------------------------------------------------------
 *
 * TrayIconCreateCmd --
 *
 *      Create tray command and (unreal) window.
 *
 * Results:
 *	Icon tray and hidden window created.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TrayIconCreateCmd(
    ClientData cd,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    Tk_Window mainWindow = (Tk_Window)cd;
    DockIcon *icon;

    icon = (DockIcon*)attemptckalloc(sizeof(DockIcon));
    if (!icon) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("running out of memory", -1));
	goto handleErrors;
    }
    memset(icon,0,sizeof(*icon));

    if (objc < 2||(objc%2)) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?option value ...?");
	goto handleErrors;
    }

    /* It's not a toplevel window by now. It really doesn't matter,
     * because it's not really shown.
     */
    icon->tkwin = Tk_CreateWindowFromPath(interp, mainWindow,
            Tcl_GetString(objv[1]),"");
    if (icon->tkwin == NULL) {
	goto handleErrors;
    }

    /* Subscribe to StructureNotify */
    TKU_AddInput(Tk_Display(icon->tkwin),
            RootWindowOfScreen(Tk_Screen(icon->tkwin)),StructureNotifyMask);
    TKU_AddInput(Tk_Display(icon->tkwin),
            RootWindow(Tk_Display(icon->tkwin),0),StructureNotifyMask);
    /* Spec says "screen 0" not "default", but... */
    TKU_AddInput(Tk_Display(icon->tkwin),
            DefaultRootWindow(Tk_Display(icon->tkwin)),StructureNotifyMask);

    /* Early tracking of DestroyNotify is essential */
    Tk_CreateEventHandler(icon->tkwin,StructureNotifyMask,
            UserIconEvent,(ClientData)icon);

    /* Now try setting options */
    icon->options = Tk_CreateOptionTable(interp,IconOptionSpec);
    /* Class name is used for retrieving defaults, so... */
    Tk_SetClass(icon->tkwin, Tk_GetUid("TrayIcon"));
    if (Tk_InitOptions(interp,(char*)icon,icon->options,icon->tkwin) != TCL_OK) {
	goto handleErrors;
    }

    icon->a_NET_SYSTEM_TRAY_Sn = DockSelectionAtomFor(icon->tkwin);
    icon->a_NET_SYSTEM_TRAY_OPCODE = Tk_InternAtom(icon->tkwin,"_NET_SYSTEM_TRAY_OPCODE");
    icon->a_NET_SYSTEM_TRAY_MESSAGE_DATA = Tk_InternAtom(icon->tkwin,"_NET_SYSTEM_TRAY_MESSAGE_DATA");
    icon->a_NET_SYSTEM_TRAY_ORIENTATION = Tk_InternAtom(icon->tkwin,"_NET_SYSTEM_TRAY_ORIENTATION");
    icon->a_NET_SYSTEM_TRAY_VISUAL = Tk_InternAtom(icon->tkwin,"_NET_SYSTEM_TRAY_VISUAL");
    icon->a_XEMBED_INFO = Tk_InternAtom(icon->tkwin,"_XEMBED_INFO");
    icon->aMANAGER = Tk_InternAtom(icon->tkwin,"MANAGER");

    icon->interp = interp;

    icon->trayManager = XGetSelectionOwner(Tk_Display(icon->tkwin), icon->a_NET_SYSTEM_TRAY_Sn);
    if (icon->trayManager) {
	XSelectInput(Tk_Display(icon->tkwin),icon->trayManager, StructureNotifyMask);
    }

    Tk_CreateGenericHandler(IconGenericHandler, (ClientData)icon);

    if (objc>3) {
	if (TrayIconConfigureMethod(icon, interp, objc-2, objv+2,
                ICON_CONF_XEMBED|ICON_CONF_IMAGE|ICON_CONF_FIRST_TIME) != TCL_OK) {
	    goto handleErrors;
	}
    }

    icon->widgetCmd = Tcl_CreateObjCommand(interp, Tcl_GetString(objv[1]),
            TrayIconObjectCmd, (ClientData)icon, TrayIconDeleteProc);

    /* Sometimes a command just can't be created... */
    if (!icon->widgetCmd) {
	goto handleErrors;
    }

    Tcl_SetObjResult(interp,objv[1]);
    return TCL_OK;

handleErrors:
    /* Rolling back */
    if (icon) {
	if (icon->options) {
	    Tk_DeleteOptionTable(icon->options);
	    icon->options = NULL;
	}
	if (icon->tkwin) {
	    /* Resources will be freed by DestroyNotify handler */
	    Tk_DestroyWindow(icon->tkwin);
	}
	ckfree((char*)icon);
    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tktray_Init --
 *
 *      Initialize the command.
 *
 * Results:
 *	Command initialized.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tktray_Init(
    Tcl_Interp *interp)
{
    Tcl_CreateObjCommand(interp, "::tk::systray::_systray",
            TrayIconCreateCmd, Tk_MainWindow(interp), NULL);
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to unix/tkUnixWm.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
1
2
3
4
5
6
7
8


9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29


30
31
32
33
34
35
36
37
38








-
-
+
+



















-
-
+
+







/*
 * tkUnixWm.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) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1991-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkUnixInt.h"

/*
 * A data structure of the following type holds information for each window
 * manager protocol (such as WM_DELETE_WINDOW) for which a handler (i.e. a Tcl
 * command) has been defined for a particular top-level window.
 */

typedef struct ProtocolHandler {
    Atom protocol;		/* Identifies the protocol. */
    struct ProtocolHandler *nextPtr;
				/* Next in list of protocol handlers for the
				 * same top-level window, or NULL for end of
				 * list. */
    Tcl_Interp *interp;		/* Interpreter in which to invoke command. */
    char command[1];		/* Tcl command to invoke when a client message
    Tcl_Interp *interp;	/* Interpreter in which to invoke command. */
    char command[TKFLEXARRAY];	/* Tcl command to invoke when a client message
				 * for this protocol arrives. The actual size
				 * of the structure varies to accommodate the
				 * needs of the actual command. THIS MUST BE
				 * THE LAST FIELD OF THE STRUCTURE. */
} ProtocolHandler;

#define HANDLER_SIZE(cmdLength) \
78
79
80
81
82
83
84
85

86
87
88
89
90
91
92
78
79
80
81
82
83
84

85
86
87
88
89
90
91
92







-
+







    char *iconName;		/* Name to display in icon. Malloced. */
    XWMHints hints;		/* Various pieces of information for window
				 * manager. */
    char *leaderName;		/* Path name of leader of window group
				 * (corresponds to hints.window_group).
				 * Malloc-ed. Note: this field doesn't get
				 * updated if leader is destroyed. */
    TkWindow *masterPtr;	/* Master window for TRANSIENT_FOR property,
    TkWindow *containerPtr;	/* Container window for TRANSIENT_FOR property,
				 * or NULL. */
    Tk_Window icon;		/* Window to use as icon for this window, or
				 * NULL. */
    Tk_Window iconFor;		/* Window for which this window is icon, or
				 * NULL if this isn't an icon for anyone. */
    int withdrawn;		/* Non-zero means window has been withdrawn. */

255
256
257
258
259
260
261
262

263
264
265
266
267
268
269
255
256
257
258
259
260
261

262
263
264
265
266
267
268
269







-
+







 *				allow the user to change the width of the
 *				window (controlled by "wm resizable" command).
 * WM_HEIGHT_NOT_RESIZABLE -	non-zero means that we're not supposed to
 *				allow the user to change the height of the
 *				window (controlled by "wm resizable" command).
 * WM_WITHDRAWN -		non-zero means that this window has explicitly
 *				been withdrawn. If it's a transient, it should
 *				not mirror state changes in the master.
 *				not mirror state changes in the container.
 */

#define WM_NEVER_MAPPED			1
#define WM_UPDATE_PENDING		2
#define WM_NEGATIVE_X			4
#define WM_NEGATIVE_Y			8
#define WM_UPDATE_SIZE_HINTS		0x10
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,			/* lostSlaveProc */
    NULL,			/* lostContentProc */
};
static const Tk_GeomMgr menubarMgrType = {
    "menubar",			/* name */
    MenubarReqProc,		/* requestProc */
    NULL,			/* lostSlaveProc */
    NULL,			/* lostContentProc */
};

/*
 * Structures of the following type are used for communication between
 * WaitForEvent, WaitRestrictProc, and WaitTimeoutProc.
 */

567
568
569
570
571
572
573
574

575
576
577
578
579
580
581
567
568
569
570
571
572
573

574
575
576
577
578
579
580
581







-
+







    WmInfo *wmPtr;
    TkDisplay *dispPtr = winPtr->dispPtr;

    wmPtr = (WmInfo *)ckalloc(sizeof(WmInfo));
    memset(wmPtr, 0, sizeof(WmInfo));
    wmPtr->winPtr = winPtr;
    wmPtr->reparent = None;
    wmPtr->masterPtr = NULL;
    wmPtr->containerPtr = NULL;
    wmPtr->numTransients = 0;
    wmPtr->hints.flags = InputHint | StateHint;
    wmPtr->hints.input = True;
    wmPtr->hints.initial_state = NormalState;
    wmPtr->hints.icon_pixmap = None;
    wmPtr->hints.icon_window = None;
    wmPtr->hints.icon_x = wmPtr->hints.icon_y = 0;
680
681
682
683
684
685
686
687

688
689

690
691
692

693
694
695
696
697
698
699
700
701
702
703

704
705
706
707
708
709
710
680
681
682
683
684
685
686

687
688

689
690
691

692
693
694
695
696
697
698
699
700
701
702

703
704
705
706
707
708
709
710







-
+

-
+


-
+










-
+







	 * Store all the window-manager-related information for the window.
	 */

	TkWmSetClass(winPtr);
	UpdateTitle(winPtr);
	UpdatePhotoIcon(winPtr);

	if (wmPtr->masterPtr != NULL) {
	if (wmPtr->containerPtr != NULL) {
	    /*
	     * Don't map a transient if the master is not mapped.
	     * Don't map a transient if the container is not mapped.
	     */

	    if (!Tk_IsMapped(wmPtr->masterPtr)) {
	    if (!Tk_IsMapped(wmPtr->containerPtr)) {
		wmPtr->withdrawn = 1;
		wmPtr->hints.initial_state = WithdrawnState;
	    }

	    /*
	     * Make sure that we actually set the transient-for property, even
	     * if we are withdrawn. [Bug 1163496]
	     */

	    XSetTransientForHint(winPtr->display, wmPtr->wrapperPtr->window,
		    wmPtr->masterPtr->wmInfoPtr->wrapperPtr->window);
		    wmPtr->containerPtr->wmInfoPtr->wrapperPtr->window);
	}

	wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
	UpdateHints(winPtr);
	UpdateWmProtocols(wmPtr);
	if (wmPtr->cmdArgv != NULL) {
	    UpdateCommand(winPtr);
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
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







-
+




-
+

-
+

-
+














-
-
+
+


-
+





-
+

-
+







	ckfree(wmPtr->clientMachine);
    }
    if (wmPtr->flags & WM_UPDATE_PENDING) {
	Tcl_CancelIdleCall(UpdateGeometryInfo, winPtr);
    }

    /*
     * Reset all transient windows whose master is the dead window.
     * Reset all transient windows whose container is the dead window.
     */

    for (wmPtr2 = winPtr->dispPtr->firstWmPtr; wmPtr2 != NULL;
	    wmPtr2 = wmPtr2->nextPtr) {
	if (wmPtr2->masterPtr == winPtr) {
	if (wmPtr2->containerPtr == winPtr) {
	    wmPtr->numTransients--;
	    Tk_DeleteEventHandler((Tk_Window) wmPtr2->masterPtr,
	    Tk_DeleteEventHandler((Tk_Window) wmPtr2->containerPtr,
		    StructureNotifyMask, WmWaitMapProc, wmPtr2->winPtr);
	    wmPtr2->masterPtr = NULL;
	    wmPtr2->containerPtr = NULL;
	    if (!(wmPtr2->flags & WM_NEVER_MAPPED)) {
		XDeleteProperty(winPtr->display, wmPtr2->wrapperPtr->window,
			Tk_InternAtom((Tk_Window) winPtr, "WM_TRANSIENT_FOR"));

		/*
		 * FIXME: Need a call like Win32's UpdateWrapper() so we can
		 * recreate the wrapper and get rid of the transient window
		 * decorations.
		 */
	    }
	}
    }
    /* ASSERT: numTransients == 0 [Bug 1789819] */

    if (wmPtr->masterPtr != NULL) {
	wmPtr2 = wmPtr->masterPtr->wmInfoPtr;
    if (wmPtr->containerPtr != NULL) {
	wmPtr2 = wmPtr->containerPtr->wmInfoPtr;

	/*
	 * If we had a master, tell them that we aren't tied to them anymore
	 * If we had a container, tell them that we aren't tied to them anymore
	 */

	if (wmPtr2 != NULL) {
	    wmPtr2->numTransients--;
	}
	Tk_DeleteEventHandler((Tk_Window) wmPtr->masterPtr,
	Tk_DeleteEventHandler((Tk_Window) wmPtr->containerPtr,
		StructureNotifyMask, WmWaitMapProc, winPtr);
	wmPtr->masterPtr = NULL;
	wmPtr->containerPtr = NULL;
    }
    ckfree(wmPtr);
    winPtr->wmInfoPtr = NULL;
}

/*
 *--------------------------------------------------------------
1177
1178
1179
1180
1181
1182
1183
1184

1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1177
1178
1179
1180
1181
1182
1183

1184
1185
1186
1187
1188
1189
1190
1191

1192
1193
1194
1195
1196
1197
1198







-
+







-







 *	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) {
1380
1381
1382
1383
1384
1385
1386
1387

1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1379
1380
1381
1382
1383
1384
1385

1386
1387
1388
1389
1390
1391
1392

1393
1394
1395
1396
1397
1398
1399







-
+






-







 * See also: TIP#231, EWMH.
 *
 *----------------------------------------------------------------------
 */

static int
WmAttributesCmd(
    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. */
{
    int attribute = 0;
    (void)tkwin;

    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));
1445
1446
1447
1448
1449
1450
1451
1452

1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1443
1444
1445
1446
1447
1448
1449

1450
1451
1452
1453
1454
1455
1456
1457

1458
1459
1460
1461
1462
1463
1464







-
+







-







 *	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;
    (void)tkwin;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->clientMachine != NULL) {
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
1629
1630
1631
1632
1633
1634
1635

1636
1637
1638
1639
1640
1641
1642
1643
1644
1645

1646
1647
1648
1649
1650
1651
1652







-
+









-







 *	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) {
1702
1703
1704
1705
1706
1707
1708
1709

1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1698
1699
1700
1701
1702
1703
1704

1705
1706
1707
1708
1709
1710
1711

1712
1713
1714
1715
1716
1717
1718







-
+






-







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







-
+











-







 *	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(
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
1803
1804
1805
1806
1807
1808
1809

1810
1811



1812
1813
1814
1815
1816




1817
1818
1819
1820
1821
1822
1823







-
+

-
-
-
+
+
+


-
-
-
-







 *	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 *interp,		/* 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)interp;
    (void)objc;
    (void)objv;

    if (Tk_IsTopLevel(frameWin)) {
	TkFocusJoin(winPtr);
	Tk_UnmapWindow(frameWin);
	TkWmDeadWindow(winPtr);
	winPtr->flags &=
		~(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED);
1866
1867
1868
1869
1870
1871
1872
1873

1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1856
1857
1858
1859
1860
1861
1862

1863
1864
1865
1866
1867
1868
1869
1870
1871

1872
1873
1874
1875
1876
1877
1878







-
+








-







 *	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;
    Window window;
    char buf[TCL_INTEGER_SPACE];
    (void)tkwin;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    window = wmPtr->reparent;
    if (window == None) {
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
1898
1899
1900
1901
1902
1903
1904

1905
1906
1907
1908
1909
1910
1911
1912
1913
1914

1915
1916
1917
1918
1919
1920
1921







-
+









-







 *	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) {
	xSign = (wmPtr->flags & WM_NEGATIVE_X) ? '-' : '+';
1970
1971
1972
1973
1974
1975
1976
1977

1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1958
1959
1960
1961
1962
1963
1964

1965
1966
1967
1968
1969
1970
1971
1972

1973
1974
1975
1976
1977
1978
1979







-
+







-







 *	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) {
2145
2146
2147
2148
2149
2150
2151
2152

2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2132
2133
2134
2135
2136
2137
2138

2139
2140
2141
2142
2143
2144
2145
2146
2147

2148
2149
2150
2151
2152
2153
2154







-
+








-







 *	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;
    Pixmap pixmap;
    const char *argv3;
    (void)tkwin;

    if ((objc < 3) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & IconPixmapHint) {
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
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







-
+






-













-
+








-
+






-
+







 *	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 (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't iconify \"%s\": override-redirect flag is set",
		winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "OVERRIDE_REDIRECT",
		NULL);
	return TCL_ERROR;
    }
    if (wmPtr->masterPtr != NULL) {
    if (wmPtr->containerPtr != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't iconify \"%s\": it is a transient",
		winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "TRANSIENT", NULL);
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't iconify %s: it is an icon for %s",
		"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));
2335
2336
2337
2338
2339
2340
2341
2342

2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2320
2321
2322
2323
2324
2325
2326

2327
2328
2329
2330
2331
2332
2333
2334

2335
2336
2337
2338
2339
2340
2341







-
+







-







 *	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;
    (void)tkwin;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->iconName != NULL) {
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
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







-
+










-







 *	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. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_PhotoHandle photo;
    Tk_PhotoImageBlock block;
    int i, size = 0, width, height, index = 0, x, y, isDefault = 0;
    unsigned long *iconPropertyData;
    (void)tkwin;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"window ?-default? image1 ?image2 ...?");
	return TCL_ERROR;
    }
    if (strcmp(Tcl_GetString(objv[3]), "-default") == 0) {
2538
2539
2540
2541
2542
2543
2544
2545

2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2521
2522
2523
2524
2525
2526
2527

2528
2529
2530
2531
2532
2533
2534
2535

2536
2537
2538
2539
2540
2541
2542







-
+







-







 *	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) {
2613
2614
2615
2616
2617
2618
2619
2620

2621
2622
2623
2624
2625
2626
2627
2595
2596
2597
2598
2599
2600
2601

2602
2603
2604
2605
2606
2607
2608
2609







-
+








    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, TkNewWindowObj(wmPtr->icon));
	    Tcl_SetObjResult(interp, Tk_NewWindowObj(wmPtr->icon));
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->hints.flags &= ~IconWindowHint;
	if (wmPtr->icon != NULL) {
	    /*
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
2698
2699
2700
2701
2702
2703
2704

2705
2706
2707


2708
2709
2710
2711
2712



2713
2714
2715
2716
2717
2718
2719







-
+


-
-
+
+



-
-
-







 *	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);
2781
2782
2783
2784
2785
2786
2787
2788

2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2760
2761
2762
2763
2764
2765
2766

2767
2768
2769
2770
2771
2772
2773
2774

2775
2776
2777
2778
2779
2780
2781







-
+







-







 *	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];
2841
2842
2843
2844
2845
2846
2847
2848

2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2819
2820
2821
2822
2823
2824
2825

2826
2827
2828
2829
2830
2831
2832
2833

2834
2835
2836
2837
2838
2839
2840







-
+







-







 *	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];
2893
2894
2895
2896
2897
2898
2899
2900

2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2870
2871
2872
2873
2874
2875
2876

2877
2878
2879
2880
2881
2882
2883
2884

2885
2886
2887
2888
2889
2890
2891







-
+







-







 *	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. */
{
    int boolean, curValue;
    XSetWindowAttributes atts;
    (void)tkwin;

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







-
+











-







 *	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 = "";
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
2995
2996
2997
2998
2999
3000
3001

3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012

3013
3014
3015
3016
3017
3018
3019







-
+










-







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
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;
    (void)tkwin;

    if ((objc < 3) || (objc > 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name? ?command?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	/*
3097
3098
3099
3100
3101
3102
3103
3104

3105
3106
3107
3108
3109
3110
3111
3071
3072
3073
3074
3075
3076
3077

3078
3079
3080
3081
3082
3083
3084
3085







-
+







	    } 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);
3131
3132
3133
3134
3135
3136
3137
3138

3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3105
3106
3107
3108
3109
3110
3111

3112
3113
3114
3115
3116
3117
3118
3119

3120
3121
3122
3123
3124
3125
3126







-
+







-







 *	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];
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
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







-
+











-







 *	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 = "";
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
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







-
+











-







 *	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", NULL };
    enum options {
	OPT_NORMAL, OPT_ICONIC, OPT_WITHDRAWN };
    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) {
3428
3429
3430
3431
3432
3433
3434
3435

3436
3437
3438
3439
3440
3441
3442
3399
3400
3401
3402
3403
3404
3405

3406
3407
3408
3409
3410
3411
3412
3413







-
+







		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't iconify \"%s\": override-redirect flag is set",
			winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "STATE",
			"OVERRIDE_REDIRECT", NULL);
		return TCL_ERROR;
	    }
	    if (wmPtr->masterPtr != NULL) {
	    if (wmPtr->containerPtr != NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't iconify \"%s\": it is a transient",
			winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "STATE", "TRANSIENT",
			NULL);
		return TCL_ERROR;
	    }
3491
3492
3493
3494
3495
3496
3497
3498

3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3462
3463
3464
3465
3466
3467
3468

3469
3470
3471
3472
3473
3474
3475
3476

3477
3478
3479
3480
3481
3482
3483







-
+







-







 *	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;
    (void)tkwin;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->title) {
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
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







-
+



-
+



-
-
+
+




-
+

-
+



-
-
+
+









-
+

-
+

-
+


-
-
+
+

-
+


-
+

-
+









-
+






-
+





-
-
+
+


-
-
+
+





-
+

-
-
-
+
+
+


-
-
-
+
+
+



-
-
+
+


-
+



-
+








-
+


-
+







    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    TkWindow *masterPtr = wmPtr->masterPtr, *w;
    TkWindow *containerPtr = wmPtr->containerPtr, *w;
    WmInfo *wmPtr2;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?master?");
	Tcl_WrongNumArgs(interp, 2, objv, "window ?window?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (masterPtr != NULL) {
	    Tcl_SetObjResult(interp, TkNewWindowObj((Tk_Window) masterPtr));
	if (containerPtr != NULL) {
	    Tcl_SetObjResult(interp, Tk_NewWindowObj((Tk_Window) containerPtr));
	}
	return TCL_OK;
    }
    if (Tcl_GetString(objv[3])[0] == '\0') {
	if (masterPtr != NULL) {
	if (containerPtr != NULL) {
	    /*
	     * If we had a master, tell them that we aren't tied to them
	     * If we had a container, tell them that we aren't tied to them
	     * anymore
	     */

	    masterPtr->wmInfoPtr->numTransients--;
	    Tk_DeleteEventHandler((Tk_Window) masterPtr, StructureNotifyMask,
	    containerPtr->wmInfoPtr->numTransients--;
	    Tk_DeleteEventHandler((Tk_Window) containerPtr, StructureNotifyMask,
		    WmWaitMapProc, winPtr);

	    /*
	     * FIXME: Need a call like Win32's UpdateWrapper() so we can
	     * recreate the wrapper and get rid of the transient window
	     * decorations.
	     */
	}

	wmPtr->masterPtr = NULL;
	wmPtr->containerPtr = NULL;
    } else {
	Tk_Window masterWin;
	Tk_Window container;

	if (TkGetWindowFromObj(interp, tkwin, objv[3], &masterWin)!=TCL_OK) {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &container)!=TCL_OK) {
	    return TCL_ERROR;
	}
	masterPtr = (TkWindow *) masterWin;
	while (!Tk_TopWinHierarchy(masterPtr)) {
	containerPtr = (TkWindow *) container;
	while (!Tk_TopWinHierarchy(containerPtr)) {
	    /*
	     * Ensure that the master window is actually a Tk toplevel.
	     * Ensure that the container window is actually a Tk toplevel.
	     */

	    masterPtr = masterPtr->parentPtr;
	    containerPtr = containerPtr->parentPtr;
	}
	Tk_MakeWindowExist((Tk_Window) masterPtr);
	Tk_MakeWindowExist((Tk_Window) containerPtr);

	if (wmPtr->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't make \"%s\" a transient: it is an icon for %s",
		    Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
	    return TCL_ERROR;
	}

	wmPtr2 = masterPtr->wmInfoPtr;
	wmPtr2 = containerPtr->wmInfoPtr;
	if (wmPtr2->wrapperPtr == NULL) {
	    CreateWrapper(wmPtr2);
	}

	if (wmPtr2->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't make \"%s\" a master: it is an icon for %s",
		    "can't make \"%s\" a container: it is an icon for %s",
		    Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
	    return TCL_ERROR;
	}

	for (w = masterPtr; w != NULL && w->wmInfoPtr != NULL;
	     w = (TkWindow *)w->wmInfoPtr->masterPtr) {
	for (w = containerPtr; w != NULL && w->wmInfoPtr != NULL;
	     w = (TkWindow *)w->wmInfoPtr->containerPtr) {
	    if (w == winPtr) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "setting \"%s\" as master creates a transient/master cycle",
		    Tk_PathName(masterPtr)));
		    "can't set \"%s\" as container: would cause management loop",
		    Tk_PathName(containerPtr)));
		Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
		return TCL_ERROR;
	    }
	}

	if (masterPtr != wmPtr->masterPtr) {
	if (containerPtr != wmPtr->containerPtr) {
	    /*
	     * Remove old master map/unmap binding before setting the new
	     * master. The event handler will ensure that transient states
	     * reflect the state of the master.
	     * Remove old container map/unmap binding before setting the new
	     * container. The event handler will ensure that transient states
	     * reflect the state of the container.
	     */

	    if (wmPtr->masterPtr != NULL) {
		wmPtr->masterPtr->wmInfoPtr->numTransients--;
		Tk_DeleteEventHandler((Tk_Window) wmPtr->masterPtr,
	    if (wmPtr->containerPtr != NULL) {
		wmPtr->containerPtr->wmInfoPtr->numTransients--;
		Tk_DeleteEventHandler((Tk_Window) wmPtr->containerPtr,
			StructureNotifyMask, WmWaitMapProc, winPtr);
	    }

	    masterPtr->wmInfoPtr->numTransients++;
	    Tk_CreateEventHandler((Tk_Window) masterPtr,
	    containerPtr->wmInfoPtr->numTransients++;
	    Tk_CreateEventHandler((Tk_Window) containerPtr,
		    StructureNotifyMask, WmWaitMapProc, winPtr);

	    wmPtr->masterPtr = masterPtr;
	    wmPtr->containerPtr = containerPtr;
	}
    }
    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	if (wmPtr->masterPtr != NULL && !Tk_IsMapped(wmPtr->masterPtr)) {
	if (wmPtr->containerPtr != NULL && !Tk_IsMapped(wmPtr->containerPtr)) {
	    if (TkpWmSetState(winPtr, WithdrawnState) == 0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"couldn't send withdraw message to window manager",
			-1));
		Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
		return TCL_ERROR;
	    }
	} else {
	    if (wmPtr->masterPtr != NULL) {
	    if (wmPtr->containerPtr != NULL) {
		XSetTransientForHint(winPtr->display,
			wmPtr->wrapperPtr->window,
			wmPtr->masterPtr->wmInfoPtr->wrapperPtr->window);
			wmPtr->containerPtr->wmInfoPtr->wrapperPtr->window);
	    } else {
		XDeleteProperty(winPtr->display, wmPtr->wrapperPtr->window,
			Tk_InternAtom((Tk_Window) winPtr,"WM_TRANSIENT_FOR"));
	    }
	}
    }
    return TCL_OK;
3694
3695
3696
3697
3698
3699
3700
3701

3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3664
3665
3666
3667
3668
3669
3670

3671
3672
3673
3674
3675
3676
3677

3678
3679
3680
3681
3682
3683
3684







-
+






-







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







-
+








-
+

-
+







	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

/*
 * Invoked when a MapNotify or UnmapNotify event is delivered for a toplevel
 * that is the master of a transient toplevel.
 * that is the container of a transient toplevel.
 */

static void
WmWaitMapProc(
    ClientData clientData,	/* Pointer to window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkWindow *winPtr = (TkWindow *)clientData;
    TkWindow *masterPtr = winPtr->wmInfoPtr->masterPtr;
    TkWindow *containerPtr = winPtr->wmInfoPtr->containerPtr;

    if (masterPtr == NULL) {
    if (containerPtr == NULL) {
	return;
    }

    if (eventPtr->type == MapNotify) {
	if (!(winPtr->wmInfoPtr->flags & WM_WITHDRAWN)) {
	    (void) TkpWmSetState(winPtr, NormalState);
	}
4521
4522
4523
4524
4525
4526
4527
4528

4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4490
4491
4492
4493
4494
4495
4496

4497
4498
4499
4500
4501

4502
4503
4504
4505
4506
4507
4508







-
+




-







 *	happens as a when-idle action).
 *
 *----------------------------------------------------------------------
 */

static void
TopLevelReqProc(
    ClientData dummy,		/* Not used. */
    TCL_UNUSED(void *),		/* Not used. */
    Tk_Window tkwin)		/* Information about window. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    (void)dummy;

    if (wmPtr == NULL) {
	return;
    }

    if ((wmPtr->width >= 0) && (wmPtr->height >= 0)) {
	/*
5490
5491
5492
5493
5494
5495
5496
5497

5498
5499
5500
5501
5502
5503
5504
5458
5459
5460
5461
5462
5463
5464

5465
5466
5467
5468
5469
5470
5471
5472







-
+







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

Changes to unix/tkUnixXId.c.

1
2
3
4
5


6
7
8
9
10
11
12
1
2
3


4
5
6
7
8
9
10
11
12



-
-
+
+







/*
 * tkUnixXId.c --
 *
 * Copyright (c) 1993 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright © 1993 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkUnixInt.h"

Changes to win/Makefile.in.

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

79
80
81
82
83
84
85
67
68
69
70
71
72
73



74

75
76
77
78
79
80
81
82







-
-
-

-
+







# Directory in which to install manual entries for Tk's C library
# procedures:
MAN3_INSTALL_DIR = $(MAN_INSTALL_DIR)/man3

# Directory in which to install manual entries for the built-in Tk commands:
MANN_INSTALL_DIR = $(MAN_INSTALL_DIR)/mann

# Libraries built with optimization switches have this additional extension
TK_DBGX = @TK_DBGX@

# Directory in which to install the pkgIndex.tcl file for loadable Tk
PKG_INSTALL_DIR		= $(LIB_INSTALL_DIR)/tk$(VERSION)$(TK_DBGX)
PKG_INSTALL_DIR		= $(LIB_INSTALL_DIR)/tk$(VERSION)

# Package index file for loadable Tk
PKG_INDEX		= $(PKG_INSTALL_DIR)/pkgIndex.tcl

# The directory containing the Tcl source and header files.
TCL_SRC_DIR		= @TCL_SRC_DIR@

125
126
127
128
129
130
131


132
133
134
135
136
137

138
139
140
141
142
143
144
145



146
147
148
149
150
151
152
122
123
124
125
126
127
128
129
130
131
132
133
134
135

136
137
138
139
140
141



142
143
144
145
146
147
148
149
150
151







+
+





-
+





-
-
-
+
+
+







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}${LIBSUFFIX}

SHARED_LIBRARIES 	= $(TK_DLL_FILE) $(TK_STUB_LIB_FILE)
STATIC_LIBRARIES	= $(TK_LIB_FILE)

WISH			= wish$(VER)${EXESUFFIX}
TKTEST			= tktest${EXEEXT}
CAT32			= cat32$(EXEEXT)
MAN2TCL			= man2tcl$(EXEEXT)
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.

164
165
166
167
168
169
170
171

172
173
174
175
176
177
178
179
180
181
182

183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
163
164
165
166
167
168
169

170
171
172
173
174
175
176
177
178
179
180

181
182
183
184
185

186
187
188
189
190
191


192
193
194
195
196
197
198







-
+










-
+




-






-
-







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@
EXEEXT		= @EXEEXT@
OBJEXT		= @OBJEXT@
STLIB_LD	= @STLIB_LD@
SHLIB_LD	= @SHLIB_LD@
SHLIB_LD_LIBS	= @SHLIB_LD_LIBS@
SHLIB_CFLAGS	= @SHLIB_CFLAGS@
SHLIB_SUFFIX	= @SHLIB_SUFFIX@
VER		= @TK_MAJOR_VERSION@@TK_MINOR_VERSION@
DOTVER		= @TK_MAJOR_VERSION@.@TK_MINOR_VERSION@
LIBS		= $(TCL_STUB_LIB_FILE) @LIBS@ @LIBS_GUI@
RMDIR		= rm -rf
MKDIR		= mkdir -p
SHELL		= @SHELL@
RM		= rm -f
COPY		= cp

262
263
264
265
266
267
268

269
270
271
272
273
274
275
276
277
278

279
280
281
282
283
284
285
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283







+










+







	tkWinColor.$(OBJEXT) \
	tkWinConfig.$(OBJEXT) \
	tkWinCursor.$(OBJEXT) \
	tkWinDialog.$(OBJEXT) \
	tkWinDraw.$(OBJEXT) \
	tkWinEmbed.$(OBJEXT) \
	tkWinFont.$(OBJEXT) \
	tkWinIco.$(OBJEXT) \
	tkWinImage.$(OBJEXT) \
	tkWinInit.$(OBJEXT) \
	tkWinKey.$(OBJEXT) \
	tkWinMenu.$(OBJEXT) \
	tkWinPixmap.$(OBJEXT) \
	tkWinPointer.$(OBJEXT) \
	tkWinRegion.$(OBJEXT) \
	tkWinScrlbr.$(OBJEXT) \
	tkWinSend.$(OBJEXT) \
	tkWinSendCom.$(OBJEXT) \
	tkWinSysTray.$(OBJEXT) \
	tkWinWindow.$(OBJEXT) \
	tkWinWm.$(OBJEXT) \
	tkWinX.$(OBJEXT) \
	stubs.$(OBJEXT) \
	tk3d.$(OBJEXT) \
	tkArgv.$(OBJEXT) \
	tkAtom.$(OBJEXT) \
488
489
490
491
492
493
494
495

496
497

498

499
500
501
502
503
504
505
486
487
488
489
490
491
492

493
494

495
496
497
498
499
500
501
502
503
504







-
+

-
+

+







	    done
	@echo "Creating package index $(PKG_INDEX)";
	@$(RM) $(PKG_INDEX);
	@(\
	echo "if {[catch {package present Tcl 8.6-}]} return";\
	echo "if {(\$$::tcl_platform(platform) eq \"unix\") && ([info exists ::env(DISPLAY)]";\
	echo "	|| ([info exists ::argv] && (\"-display\" in \$$::argv)))} {";\
	echo "    package ifneeded Tk $(VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir .. .. bin libtk$(VERSION).dll]] Tk]";\
	echo "    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 "}";\
	echo "package ifneeded Tk $(VERSION)$(PATCH_LEVEL) [list package require -exact tk $(VERSION)$(PATCH_LEVEL)]";\
	) > $(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)"; \
	    fi; \
673
674
675
676
677
678
679






680
681
682
683
684
685
686
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691







+
+
+
+
+
+








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
706
707
708
709
710
711
712
713

714
715
716
717
718
719
720
711
712
713
714
715
716
717

718
719
720
721
722
723
724
725







-
+








.rc.$(RES):
	$(RC) @RC_OUT@ $@ @RC_TYPE@ @RC_DEFINES@ @RC_INCLUDE@ "$(GENERIC_DIR_NATIVE)" @RC_INCLUDE@ "$(TCL_GENERIC_NATIVE)" @RC_INCLUDE@ "$(RC_DIR_NATIVE)" @DEPARG@

depend:

cleanhelp:
	$(RM) *.hlp *.cnt *.hpj *.GID *.rtf man2tcl${EXEEXT}
	$(RM) *.hlp *.cnt *.hpj *.GID *.rtf man2tcl.exe

clean: cleanhelp
	$(RM) *.lib *.a *.exp *.dll *.res *.${OBJEXT} *~ \#* TAGS a.out
	$(RM) $(WISH) $(TKTEST) $(CAT32)
	$(RM) *.pch *.ilk *.pdb

distclean: clean

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

3
4
5

6
7
8
9
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
25

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










47
48



49
50







51









52
53
54
55





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

75
76
77
78
79
80
81
82
83







84
85
86
87
88
89
90
91
92


93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108

109
110
111
112




















113
114
115
116
117
118
119


-
+


-
+










+
-
+
+






-
+









+
+
+
+
+
+
+
+



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


-
+








-
-
-
-
-
-
-








+
-
-
+
+
+
+
+











-
+



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







#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69.
# Generated by GNU Autoconf 2.70 for tk 8.7.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
# Copyright (C) 1992-1996, 1998-2017, 2020 Free Software Foundation, Inc.
#
#
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##

# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
as_nop=:
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
if test ${ZSH_VERSION+y} && (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
else $as_nop
  case `(set -o) 2>/dev/null` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;
esac
fi



# Reset variables that may have inherited troublesome values from
# the environment.

# IFS needs to be set, to space, tab, and newline, in precisely that order.
# (If _AS_PATH_WALK were called with IFS unset, it would have the
# side effect of setting IFS to empty, thus disabling word splitting.)
# Quoting is to prevent editors from complaining about space-tab.
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 --'
IFS=" ""	$as_nl"

elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
  as_echo='printf %s\n'
  as_echo_n='printf %s'
PS1='$ '
PS2='> '
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
PS4='+ '
      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

# Ensure predictable behavior from utilities with locale-dependent output.
LC_ALL=C
export LC_ALL
    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
LANGUAGE=C
export LANGUAGE

# We cannot yet rely on "unset" to work, but we need these variables
# to be unset--not just set to an empty or harmless value--now, to
# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh).  This construct
# also avoids known problems related to "unset" and subshell syntax
# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
do eval test \${$as_var+y} \
  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
done

# Ensure that fds 0, 1, and 2 are open.
if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
if (exec 3>&2)            ; then :; else exec 2>/dev/null; fi

# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
if ${PATH_SEPARATOR+false} :; then
  PATH_SEPARATOR=:
  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
      PATH_SEPARATOR=';'
  }
fi


# IFS
# We need space, tab and new line, in precisely that order.  Quoting is
# there to prevent editors from complaining about space-tab.
# (If _AS_PATH_WALK were called with IFS unset, it would disable word
# splitting by setting IFS to empty value.)
IFS=" ""	$as_nl"

# Find who we are.  Look in the path if we contain no directory separator.
as_myself=
case $0 in #((
  *[\\/]* ) as_myself=$0 ;;
  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    test -r "$as_dir$0" && as_myself=$as_dir$0 && break
  done
IFS=$as_save_IFS

     ;;
esac
# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
  as_myself=$0
fi
if test ! -f "$as_myself"; then
  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
  exit 1
fi

# Unset variables that we do not need and which cause bugs (e.g. in
# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
# suppresses any "Segmentation fault" message there.  '((' could
# trigger a bug in pdksh 5.2.14.
for as_var in BASH_ENV ENV MAIL MAILPATH
do eval test x\${$as_var+set} = xset \
  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
done
PS1='$ '
PS2='> '
PS4='+ '

# NLS nuisances.
LC_ALL=C
export LC_ALL
LANGUAGE=C
export LANGUAGE

# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH

# Use a proper internal environment variable to ensure we don't fall
  # into an infinite loop, continuously re-executing ourselves.
  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
    _as_can_reexec=no; export _as_can_reexec;
    # We cannot yet assume a decent shell, so we have to provide a
# neutralization value for shells without unset; and this also
148
149
150
151
152
153
154
155
156


157
158
159
160
161



162
163
164
165
166
167
168

169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188


189
190

191
192
193


194
195
196
197
198
199
200


201
202

203
204
205


206
207

208
209
210
211
212

213




214
215
216
217
218
219

220
221


222
223


224
225
226
227
228
229
230





231
232



233
234

235

236
237
238


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

257
258
259
260
261
262
263
264
265







266
267

268
269
270
271
272
273
274
127
128
129
130
131
132
133


134
135
136
137
138
139

140
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168

169
170
171

172
173
174
175
176
177
178
179
180
181
182
183

184
185
186

187
188
189

190
191
192

193
194
195
196
197
198
199

200
201
202
203
204
205
206
207
208

209
210

211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
226
227


228
229
230
231

232

233
234
235

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

255
256
257
258






259
260
261
262
263
264
265
266

267
268
269
270
271
272
273
274







-
-
+
+




-
+
+
+






-
+



















-
+
+

-
+



+
+






-
+
+

-
+


-
+
+

-
+





+
-
+
+
+
+





-
+

-
+
+

-
+
+







+
+
+
+
+
-
-
+
+
+

-
+
-
+


-
+
+

















-
+



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

-
+







  *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
printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
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 :
  as_bourne_compatible="as_nop=:
if test \${ZSH_VERSION+y} && (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
else \$as_nop
  case \`(set -o) 2>/dev/null\` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;
esac
fi
"
  as_required="as_fn_return () { (exit \$1); }
as_fn_success () { as_fn_return 0; }
as_fn_failure () { as_fn_return 1; }
as_fn_ret_success () { return 0; }
as_fn_ret_failure () { return 1; }

exitcode=0
as_fn_success || { exitcode=1; echo as_fn_success failed.; }
as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
if ( set x; as_fn_ret_success y && test x = \"\$1\" )
then :

else
else \$as_nop
  exitcode=1; echo positional parameters were not saved.
fi
test x\$exitcode = x0 || exit 1
blah=\$(echo \$(echo blah))
test x\"\$blah\" = xblah || 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 :
  if (eval "$as_required") 2>/dev/null
then :
  as_have_required=yes
else
else $as_nop
  as_have_required=no
fi
  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null
then :

else
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
  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
	     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 :
		    as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 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 :
		   if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null
then :
  break 2
fi
fi
	   done;;
       esac
  as_found=false
done
IFS=$as_save_IFS
if $as_found
then :

else $as_nop
$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 :
  if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
	      as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null
then :
  CONFIG_SHELL=$SHELL as_have_required=yes
fi; }
fi
IFS=$as_save_IFS
fi


      if test "x$CONFIG_SHELL" != x; then :
      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
printf "%s\n" "$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."
    if test x$as_have_required = xno
then :
  printf "%s\n" "$0: This script requires a shell more modern than all"
  printf "%s\n" "$0: the shells that I found on your system."
  if test ${ZSH_VERSION+y} ; then
    printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should"
    printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later."
  else
    $as_echo "$0: Please tell [email protected] about your system,
    printf "%s\n" "$0: Please tell [email protected] 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
286
287
288
289
290
291
292

293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310








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

326
327
328
329
330
331
332
333
334

335
336
337
338
339
340
341
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333

334
335
336
337
338
339
340
341
342

343
344
345
346
347
348
349
350







+


















+
+
+
+
+
+
+
+














-
+








-
+







# ---------------
# 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_nop
# ---------
# Do nothing but, unlike ":", preserve the value of $?.
as_fn_nop ()
{
  return $?
}
as_nop=as_fn_nop

# 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=`printf "%s\n" "$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" |
printf "%s\n" X"$as_dir" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q
366
367
368
369
370
371
372
373


374
375
376
377
378

379
380
381
382
383
384
385
386
387
388
389
390


391
392
393
394
395

396
397
398
399
400
401








402
403
404
405
406
407
408
409
410
411
412
413

414
415

416
417
418
419
420
421
422
375
376
377
378
379
380
381

382
383
384
385
386
387

388
389
390
391
392
393
394
395
396
397
398
399

400
401
402
403
404
405

406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431

432
433

434
435
436
437
438
439
440
441







-
+
+




-
+











-
+
+




-
+






+
+
+
+
+
+
+
+











-
+

-
+







} # 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 :
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
else $as_nop
  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 :
if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
then :
  eval 'as_fn_arith ()
  {
    as_val=$(( $* ))
  }'
else
else $as_nop
  as_fn_arith ()
  {
    as_val=`expr "$@" || test $? -eq 1`
  }
fi # as_fn_arith

# as_fn_nop
# ---------
# Do nothing but, unlike ":", preserve the value of $?.
as_fn_nop ()
{
  return $?
}
as_nop=as_fn_nop

# 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
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
  fi
  $as_echo "$as_me: error: $2" >&2
  printf "%s\n" "$as_me: error: $2" >&2
  as_fn_exit $as_status
} # as_fn_error

if expr a : '\(a\)' >/dev/null 2>&1 &&
   test "X`expr 00001 : '.*\(...\)'`" = X001; then
  as_expr=expr
else
435
436
437
438
439
440
441
442

443
444
445
446
447
448
449
454
455
456
457
458
459
460

461
462
463
464
465
466
467
468







-
+







  as_dirname=false
fi

as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
	 X"$0" : 'X\(//\)$' \| \
	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X/"$0" |
printf "%s\n" X/"$0" |
    sed '/^.*\/\([^/][^/]*\)\/*$/{
	    s//\1/
	    q
	  }
	  /^X\/\(\/\/\)$/{
	    s//\1/
	    q
479
480
481
482
483
484
485
486

487
488
489
490
491
492
493
494
495
496
497
498
499




500
501
502
503
504
505
506
507
508
509
510
511







512
513
514
515
516
517
518
498
499
500
501
502
503
504

505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548







-
+













+
+
+
+












+
+
+
+
+
+
+







      N
      :loop
      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
      t loop
      s/-\n.*//
    ' >$as_me.lineno &&
  chmod +x "$as_me.lineno" ||
    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
    { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }

  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
  # already done that, so ensure we don't try to do so again and fall
  # in an infinite loop.  This has already happened in practice.
  _as_can_reexec=no; export _as_can_reexec
  # Don't try to exec as it changes $[0], causing all sort of problems
  # (the dirname of $[0] is not the place where we might find the
  # original and so on.  Autoconf is especially sensitive to this).
  . "./$as_me.lineno"
  # Exit status is that of the last command.
  exit
}


# Determine whether it's possible to make 'echo' print without a newline.
# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
# for compatibility with existing Makefiles.
ECHO_C= ECHO_N= ECHO_T=
case `echo -n x` in #(((((
-n*)
  case `echo 'xy\c'` in
  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
  xy)  ECHO_C='\c';;
  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
       ECHO_T='	';;
  esac;;
*)
  ECHO_N='-n';;
esac

# For backward compatibility with old third-party macros, we provide
# the shell variables $as_echo and $as_echo_n.  New code should use
# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
as_echo='printf %s\n'
as_echo_n='printf %s'


rm -f conf$$ conf$$.exe conf$$.file
if test -d conf$$.dir; then
  rm -f conf$$.dir/conf$$.file
else
  rm -f conf$$.dir
  mkdir conf$$.dir 2>/dev/null
571
572
573
574
575
576
577
578
579
580
581
582
583






584
585
586
587
588
589
590



591
592

593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617









618
619
620
621

622
623
624
625
626
627
628
601
602
603
604
605
606
607






608
609
610
611
612
613
614
615
616
617



618
619
620
621

622



623





624
625



626
627



628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654







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




-
-
-
+
+
+

-
+
-
-
-

-
-
-
-
-


-
-
-


-
-
-






+
+
+
+
+
+
+
+
+




+







LIBOBJS=
cross_compiling=no
subdirs=
MFLAGS=
MAKEFLAGS=

# Identity of this package.
PACKAGE_NAME=
PACKAGE_TARNAME=
PACKAGE_VERSION=
PACKAGE_STRING=
PACKAGE_BUGREPORT=
PACKAGE_URL=
PACKAGE_NAME='tk'
PACKAGE_TARNAME='tk'
PACKAGE_VERSION='8.7'
PACKAGE_STRING='tk 8.7'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''

ac_unique_file="../generic/tk.h"
# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#include <stddef.h>
#ifdef HAVE_STDIO_H
# include <stdio.h>
#endif
#ifdef HAVE_SYS_STAT_H
#ifdef HAVE_STDLIB_H
# include <sys/stat.h>
#endif
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
#  include <stdlib.h>
# endif
#endif
#ifdef HAVE_STRING_H
# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
#  include <memory.h>
# endif
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
#endif
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif"

ac_header_c_list=
ac_subst_vars='LTLIBOBJS
LIBOBJS
RES
RC_DEFINES
RC_DEFINE
RC_INCLUDE
RC_TYPE
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688



689
690
691

692
693
694
695
696
697
698
686
687
688
689
690
691
692

693
694
695
696
697
698
699
700
701
702

703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726







-










-










+
+
+



+







CC_EXENAME
CC_OBJNAME
DEPARG
EXTRA_CFLAGS
CFG_TK_EXPORT_FILE_SUFFIX
CFG_TK_UNSHARED_LIB_SUFFIX
CFG_TK_SHARED_LIB_SUFFIX
TCL_DBGX
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_DBGX
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
EGREP
GREP
CPP
LDFLAGS_DEFAULT
CFLAGS_DEFAULT
MAN2TCLFLAGS
CFLAGS_NOLTO
CFLAGS_WARNING
CFLAGS_OPTIMIZE
CFLAGS_DEBUG
DL_LIBS
WINE
CYGPATH
TCL_DEFS
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
735
736
737
738
739
740
741



742
743
744
745
746
747
748







-
-
-







TCL_BIN_DIR
TCL_VERSION
SHARED_BUILD
SET_MAKE
RC
RANLIB
AR
EGREP
GREP
CPP
OBJEXT
EXEEXT
ac_ct_CC
CPPFLAGS
LDFLAGS
CFLAGS
CC
736
737
738
739
740
741
742

743
744
745
746
747
748
749
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775







+







pdfdir
dvidir
htmldir
infodir
docdir
oldincludedir
includedir
runstatedir
localstatedir
sharedstatedir
sysconfdir
datadir
datarootdir
libexecdir
sbindir
812
813
814
815
816
817
818

819
820
821

822
823
824
825
826
827
828
838
839
840
841
842
843
844
845
846
847

848
849
850
851
852
853
854
855







+


-
+







sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
datarootdir='${prefix}/share'
datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE}'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
infodir='${datarootdir}/info'
htmldir='${docdir}'
dvidir='${docdir}'
pdfdir='${docdir}'
psdir='${docdir}'
libdir='${exec_prefix}/lib'
localedir='${datarootdir}/locale'
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
868
869
870
871
872
873
874


875
876
877
878
879
880
881







-
-








  case $ac_option in
  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
  *=)   ac_optarg= ;;
  *)    ac_optarg=yes ;;
  esac

  # Accept the important Cygnus configure options, so we can diagnose typos.

  case $ac_dashdash$ac_option in
  --)
    ac_dashdash=yes ;;

  -bindir | --bindir | --bindi | --bind | --bin | --bi)
    ac_prev=bindir ;;
  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
883
884
885
886
887
888
889
890

891
892

893
894
895
896
897
898
899
908
909
910
911
912
913
914

915
916

917
918
919
920
921
922
923
924







-
+

-
+







  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
    datarootdir=$ac_optarg ;;

  -disable-* | --disable-*)
    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid feature name: $ac_useropt"
      as_fn_error $? "invalid feature name: \`$ac_useropt'"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    ac_useropt=`printf "%s\n" "$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
909
910
911
912
913
914
915
916

917
918

919
920
921
922
923
924
925
934
935
936
937
938
939
940

941
942

943
944
945
946
947
948
949
950







-
+

-
+







  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
    dvidir=$ac_optarg ;;

  -enable-* | --enable-*)
    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid feature name: $ac_useropt"
      as_fn_error $? "invalid feature name: \`$ac_useropt'"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
    case $ac_user_opts in
      *"
"enable_$ac_useropt"
"*) ;;
      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac
1063
1064
1065
1066
1067
1068
1069









1070
1071
1072
1073
1074
1075
1076
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110







+
+
+
+
+
+
+
+
+







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

  -runstatedir | --runstatedir | --runstatedi | --runstated \
  | --runstate | --runstat | --runsta | --runst | --runs \
  | --run | --ru | --r)
    ac_prev=runstatedir ;;
  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
  | --run=* | --ru=* | --r=*)
    runstatedir=$ac_optarg ;;

  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
    ac_prev=sbindir ;;
  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
  | --sbi=* | --sb=*)
    sbindir=$ac_optarg ;;

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







-
+

-
+













-
+

-
+







  -version | --version | --versio | --versi | --vers | -V)
    ac_init_version=: ;;

  -with-* | --with-*)
    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid package name: $ac_useropt"
      as_fn_error $? "invalid package name: \`$ac_useropt'"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
    case $ac_user_opts in
      *"
"with_$ac_useropt"
"*) ;;
      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac
    eval with_$ac_useropt=\$ac_optarg ;;

  -without-* | --without-*)
    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid package name: $ac_useropt"
      as_fn_error $? "invalid package name: \`$ac_useropt'"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
    case $ac_user_opts in
      *"
"with_$ac_useropt"
"*) ;;
      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac
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
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







-
+

-
+















-
+







-
+







      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
    esac
    eval $ac_envvar=\$ac_optarg
    export $ac_envvar ;;

  *)
    # FIXME: should be removed in autoconf 3.0.
    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
    printf "%s\n" "$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
      printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2
    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
    ;;

  esac
done

if test -n "$ac_prev"; then
  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
  as_fn_error $? "missing argument to $ac_option"
fi

if test -n "$ac_unrecognized_opts"; then
  case $enable_option_checking in
    no) ;;
    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
    *)     printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
  esac
fi

# Check all directory arguments for consistency.
for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
		datadir sysconfdir sharedstatedir localstatedir includedir \
		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
		libdir localedir mandir
		libdir localedir mandir runstatedir
do
  eval ac_val=\$$ac_var
  # Remove trailing slashes.
  case $ac_val in
    */ )
      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
      eval $ac_var=\$ac_val;;
1257
1258
1259
1260
1261
1262
1263
1264

1265
1266
1267
1268
1269
1270
1271
1291
1292
1293
1294
1295
1296
1297

1298
1299
1300
1301
1302
1303
1304
1305







-
+







  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" |
printf "%s\n" X"$as_myself" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q
1314
1315
1316
1317
1318
1319
1320
1321

1322
1323
1324
1325
1326
1327
1328
1348
1349
1350
1351
1352
1353
1354

1355
1356
1357
1358
1359
1360
1361
1362







-
+







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







+








-
+











-
+
+
+







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]
  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
  --libdir=DIR            object code libraries [EPREFIX/lib]
  --includedir=DIR        C header files [PREFIX/include]
  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
  --infodir=DIR           info documentation [DATAROOTDIR/info]
  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
  --mandir=DIR            man documentation [DATAROOTDIR/man]
  --docdir=DIR            documentation root [DATAROOTDIR/doc/PACKAGE]
  --docdir=DIR            documentation root [DATAROOTDIR/doc/tk]
  --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.7:";;
   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-shared         build and link with shared libraries (default: on)
1422
1423
1424
1425
1426
1427
1428
1429

1430
1431

1432
1433
1434
1435
1436
1437
1438
1459
1460
1461
1462
1463
1464
1465

1466
1467

1468
1469
1470
1471
1472
1473
1474
1475







-
+

-
+







      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
      continue
    ac_builddir=.

case "$ac_dir" in
.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
*)
  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
  ac_dir_suffix=/`printf "%s\n" "$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_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
  case $ac_top_builddir_sub in
  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
  esac ;;
esac
ac_abs_top_builddir=$ac_pwd
ac_abs_builddir=$ac_pwd$ac_dir_suffix
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
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







-
+
+







-
+








-
-
+
+

-
+
















-
+






-
+







-
+



-
+
+

-
-
+
+








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













-
+







-
+



+
-
+

-
-
+
+








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

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

-




-
-
+
+

-
+







    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
    ac_top_srcdir=$ac_top_build_prefix$srcdir
    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
esac
ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix

    cd "$ac_dir" || { ac_status=$?; continue; }
    # Check for guested configure.
    # Check for configure.gnu first; this name is used for a wrapper for
    # Metaconfig's "Configure" on case-insensitive file systems.
    if test -f "$ac_srcdir/configure.gnu"; then
      echo &&
      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
    elif test -f "$ac_srcdir/configure"; then
      echo &&
      $SHELL "$ac_srcdir/configure" --help=recursive
    else
      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
      printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2
    fi || ac_status=$?
    cd "$ac_pwd" || { ac_status=$?; break; }
  done
fi

test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
  cat <<\_ACEOF
configure
generated by GNU Autoconf 2.69
tk configure 8.7
generated by GNU Autoconf 2.70

Copyright (C) 2012 Free Software Foundation, Inc.
Copyright (C) 2020 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
  exit
fi

## ------------------------ ##
## Autoconf initialization. ##
## ------------------------ ##

# ac_fn_c_try_compile LINENO
# --------------------------
# Try to compile conftest.$ac_ext, and return whether this succeeded.
ac_fn_c_try_compile ()
{
  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
  rm -f conftest.$ac_objext
  rm -f conftest.$ac_objext conftest.beam
  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
printf "%s\n" "$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
  printf "%s\n" "$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 :
       } && test -s conftest.$ac_objext
then :
  ac_retval=0
else
  $as_echo "$as_me: failed program was:" >&5
else $as_nop
  printf "%s\n" "$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_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
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
printf %s "checking for $2... " >&6; }
if eval test \${$3+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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 $as_nop
  eval "$3=no"
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
eval ac_res=\$$3
	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
printf "%s\n" "$ac_res" >&6; }
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

} # ac_fn_c_check_header_compile

# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
# -------------------------------------------
# Tests whether TYPE exists after having included INCLUDES, setting cache
# variable VAR accordingly.
ac_fn_c_check_type ()
{
  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
printf %s "checking for $2... " >&6; }
if eval test \${$3+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  eval "$3=no"
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$4
int
main (void)
{
if (sizeof ($2))
	 return 0;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$4
int
main (void)
{
if (sizeof (($2)))
	    return 0;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :

else $as_nop
  eval "$3=yes"
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
eval ac_res=\$$3
	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
printf "%s\n" "$ac_res" >&6; }
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

} # ac_fn_c_check_type

# 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
printf "%s\n" "$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
  printf "%s\n" "$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 :
then :
  ac_retval=0
else
  $as_echo "$as_me: failed program was:" >&5
else $as_nop
  printf "%s\n" "$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
ac_configure_args_raw=
for ac_arg
# ----------------------
# 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
do
  case $ac_arg 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_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
  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
  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

  as_fn_append ac_configure_args_raw " '$ac_arg'"
       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

done
} # ac_fn_c_try_run

# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
# -------------------------------------------------------
# Tests whether HEADER exists, giving a warning if it cannot be compiled using
# the include files in INCLUDES and setting the cache variable VAR
# accordingly.
ac_fn_c_check_header_mongrel ()
{
  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
  if eval \${$3+:} false; then :
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
if eval \${$3+:} false; then :
  $as_echo_n "(cached) " >&6
fi
eval ac_res=\$$3
	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
else
  # Is the header compilable?
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
$as_echo_n "checking $2 usability... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$4
#include <$2>
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
  ac_header_compiler=yes
else
  ac_header_compiler=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
$as_echo "$ac_header_compiler" >&6; }

# Is the header present?
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
$as_echo_n "checking $2 presence... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <$2>
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :
  ac_header_preproc=yes
else
  ac_header_preproc=no
fi
rm -f conftest.err conftest.i conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
$as_echo "$ac_header_preproc" >&6; }

# So?  What about this header?
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
  yes:no: )
case $ac_configure_args_raw in
  *$as_nl*)
    { $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:* )
    ac_safe_unquote= ;;
  *)
    { $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; }
    ac_unsafe_z='|&;<>()$`\\"*?[ ''	' # This string ends in space, tab.
    ac_unsafe_a="$ac_unsafe_z#~"
fi
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

    ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g"
} # ac_fn_c_check_header_mongrel

    ac_configure_args_raw=`      printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;;
# 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
esac
  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.7, which was
generated by GNU Autoconf 2.70.  Invocation command line was

  $ $0 $@
  $ $0$ac_configure_args_raw

_ACEOF
exec 5>>config.log
{
cat <<_ASUNAME
## --------- ##
## Platform. ##
1757
1758
1759
1760
1761
1762
1763

1764
1765





1766
1767
1768
1769
1770
1771
1772
1747
1748
1749
1750
1751
1752
1753
1754


1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766







+
-
-
+
+
+
+
+








_ASUNAME

as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    $as_echo "PATH: $as_dir"
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    printf "%s\n" "PATH: $as_dir"
  done
IFS=$as_save_IFS

} >&5

cat >&5 <<_ACEOF

1793
1794
1795
1796
1797
1798
1799
1800

1801
1802
1803
1804
1805
1806
1807
1787
1788
1789
1790
1791
1792
1793

1794
1795
1796
1797
1798
1799
1800
1801







-
+







  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=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
    esac
    case $ac_pass in
    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
    2)
      as_fn_append ac_configure_args1 " '$ac_arg'"
      if test $ac_must_keep_next = true; then
	ac_must_keep_next=false # Got value, back to normal.
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
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







+
+




-
+










-
-
+
+








# When interrupted or exit'd, cleanup temporary files, and complete
# config.log.  We remove comments because anyway the quotes in there
# would cause problems or look ugly.
# WARNING: Use '\'' to represent an apostrophe within the trap.
# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
trap 'exit_status=$?
  # Sanitize IFS.
  IFS=" ""	$as_nl"
  # Save into config.log some information that might help in debugging.
  {
    echo

    $as_echo "## ---------------- ##
    printf "%s\n" "## ---------------- ##
## Cache variables. ##
## ---------------- ##"
    echo
    # The following way of writing the cache mishandles newlines in values,
(
  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
    eval ac_val=\$$ac_var
    case $ac_val in #(
    *${as_nl}*)
      case $ac_var in #(
      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
      *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
printf "%s\n" "$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
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
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







-
+







-
+

-
+




-
+







-
+

-
+





-
+







-
-
+
+













-
+



-
-
+
-

-
-
+
-

-
-
+
-

-
-
+
-

-
-
+
-

-
-
+
-




-
-

-
-
+
-
-
-
-

-
+
-

-
+
-

+
-
+

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


-
-
+
+









-
-
+
+






-
-
+
+



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










-
-
+
+


-
-
+
+








-
-
+
+


-
-
+
+


-
-
-
-
+
+
+
+





-
+









-
-
-
-
-
+
+
+
+
+
+










+







      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
      ;;
    esac |
    sort
)
    echo

    $as_echo "## ----------------- ##
    printf "%s\n" "## ----------------- ##
## Output variables. ##
## ----------------- ##"
    echo
    for ac_var in $ac_subst_vars
    do
      eval ac_val=\$$ac_var
      case $ac_val in
      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
      *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
      esac
      $as_echo "$ac_var='\''$ac_val'\''"
      printf "%s\n" "$ac_var='\''$ac_val'\''"
    done | sort
    echo

    if test -n "$ac_subst_files"; then
      $as_echo "## ------------------- ##
      printf "%s\n" "## ------------------- ##
## File substitutions. ##
## ------------------- ##"
      echo
      for ac_var in $ac_subst_files
      do
	eval ac_val=\$$ac_var
	case $ac_val in
	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
	*\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
	esac
	$as_echo "$ac_var='\''$ac_val'\''"
	printf "%s\n" "$ac_var='\''$ac_val'\''"
      done | sort
      echo
    fi

    if test -s confdefs.h; then
      $as_echo "## ----------- ##
      printf "%s\n" "## ----------- ##
## confdefs.h. ##
## ----------- ##"
      echo
      cat confdefs.h
      echo
    fi
    test "$ac_signal" != 0 &&
      $as_echo "$as_me: caught signal $ac_signal"
    $as_echo "$as_me: exit $exit_status"
      printf "%s\n" "$as_me: caught signal $ac_signal"
    printf "%s\n" "$as_me: exit $exit_status"
  } >&5
  rm -f core *.core core.conftest.* &&
    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
    exit $exit_status
' 0
for ac_signal in 1 2 13 15; do
  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
done
ac_signal=0

# confdefs.h avoids OS command line length limits that DEFS can exceed.
rm -f -r conftest* confdefs.h

$as_echo "/* confdefs.h */" > confdefs.h
printf "%s\n" "/* confdefs.h */" > confdefs.h

# Predefined preprocessor variables.

cat >>confdefs.h <<_ACEOF
#define PACKAGE_NAME "$PACKAGE_NAME"
printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_VERSION "$PACKAGE_VERSION"
printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_STRING "$PACKAGE_STRING"
printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_URL "$PACKAGE_URL"
printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h
_ACEOF


# Let the site file select an alternate cache file if it wants to.
# Prefer an explicitly selected file to automatically selected ones.
ac_site_file1=NONE
ac_site_file2=NONE
if test -n "$CONFIG_SITE"; then
  # We do not want a PATH search for config.site.
  case $CONFIG_SITE in #((
  ac_site_files="$CONFIG_SITE"
    -*)  ac_site_file1=./$CONFIG_SITE;;
    */*) ac_site_file1=$CONFIG_SITE;;
    *)   ac_site_file1=./$CONFIG_SITE;;
  esac
elif test "x$prefix" != xNONE; then
  ac_site_file1=$prefix/share/config.site
  ac_site_files="$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
  ac_site_files="$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"
for ac_site_file in $ac_site_files
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;}
  case $ac_site_file in #(
  */*) :
     ;; #(
  *) :
    ac_site_file=./$ac_site_file ;;
esac
  if test -f "$ac_site_file" && test -r "$ac_site_file"; then
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;}
    sed 's/^/| /' "$ac_site_file" >&5
    . "$ac_site_file" \
      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
      || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
printf "%s\n" "$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;}
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
printf "%s\n" "$as_me: loading cache $cache_file" >&6;}
    case $cache_file in
      [\\/]* | ?:[\\/]* ) . "$cache_file";;
      *)                      . "./$cache_file";;
    esac
  fi
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
$as_echo "$as_me: creating cache $cache_file" >&6;}
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
printf "%s\n" "$as_me: creating cache $cache_file" >&6;}
  >$cache_file
fi

# Test code for whether the C compiler supports C89 (global declarations)
ac_c_conftest_c89_globals='
/* Does the compiler advertise C89 conformance?
   Do not test the value of __STDC__, because some compilers set it to 0
   while being otherwise adequately conformant. */
#if !defined __STDC__
# error "Compiler does not advertise C89 conformance"
#endif

#include <stddef.h>
#include <stdarg.h>
struct stat;
/* Most of the following tests are stolen from RCS 5.7 src/conf.sh.  */
struct buf { int x; };
struct buf * (*rcsopen) (struct buf *, struct stat *, int);
static char *e (p, i)
     char **p;
     int i;
{
  return p[i];
}
static char *f (char * (*g) (char **, int), char **p, ...)
{
  char *s;
  va_list v;
  va_start (v,p);
  s = g (p, va_arg (v,int));
  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 do not provoke an error unfortunately, instead are silently treated
   as an "x".  The following induces an error, until -std is added to get
   proper ANSI mode.  Curiously \x00 != x always comes out true, for an
   array size at least.  It is necessary to write \x00 == 0 to get something
   that is true only with -std.  */
int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1];

/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
   inside strings and character constants.  */
#define FOO(x) '\''x'\''
int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1];

int test (int i, double x);
struct s1 {int (*f) (int a);};
struct s2 {int (*f) (double a);};
int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int),
               int, int);'

# Test code for whether the C compiler supports C89 (body of main).
ac_c_conftest_c89_main='
ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]);
'

# Test code for whether the C compiler supports C99 (global declarations)
ac_c_conftest_c99_globals='
// Does the compiler advertise C99 conformance?
#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
# error "Compiler does not advertise C99 conformance"
#endif

#include <stdbool.h>
extern int puts (const char *);
extern int printf (const char *, ...);
extern int dprintf (int, const char *, ...);
extern void *malloc (size_t);

// Check varargs macros.  These examples are taken from C99 6.10.3.5.
// dprintf is used instead of fprintf to avoid needing to declare
// FILE and stderr.
#define debug(...) dprintf (2, __VA_ARGS__)
#define showlist(...) puts (#__VA_ARGS__)
#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
static void
test_varargs_macros (void)
{
  int x = 1234;
  int y = 5678;
  debug ("Flag");
  debug ("X = %d\n", x);
  showlist (The first, second, and third items.);
  report (x>y, "x is %d but y is %d", x, y);
}

// Check long long types.
#define BIG64 18446744073709551615ull
#define BIG32 4294967295ul
#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
#if !BIG_OK
  #error "your preprocessor is broken"
#endif
#if BIG_OK
#else
  #error "your preprocessor is broken"
#endif
static long long int bignum = -9223372036854775807LL;
static unsigned long long int ubignum = BIG64;

struct incomplete_array
{
  int datasize;
  double data[];
};

struct named_init {
  int number;
  const wchar_t *name;
  double average;
};

typedef const char *ccp;

static inline int
test_restrict (ccp restrict text)
{
  // See if C++-style comments work.
  // Iterate through items via the restricted pointer.
  // Also check for declarations in for loops.
  for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i)
    continue;
  return 0;
}

// Check varargs and va_copy.
static bool
test_varargs (const char *format, ...)
{
  va_list args;
  va_start (args, format);
  va_list args_copy;
  va_copy (args_copy, args);

  const char *str = "";
  int number = 0;
  float fnumber = 0;

  while (*format)
    {
      switch (*format++)
	{
	case '\''s'\'': // string
	  str = va_arg (args_copy, const char *);
	  break;
	case '\''d'\'': // int
	  number = va_arg (args_copy, int);
	  break;
	case '\''f'\'': // float
	  fnumber = va_arg (args_copy, double);
	  break;
	default:
	  break;
	}
    }
  va_end (args_copy);
  va_end (args);

  return *str && number && fnumber;
}
'

# Test code for whether the C compiler supports C99 (body of main).
ac_c_conftest_c99_main='
  // Check bool.
  _Bool success = false;
  success |= (argc != 0);

  // Check restrict.
  if (test_restrict ("String literal") == 0)
    success = true;
  char *restrict newvar = "Another string";

  // Check varargs.
  success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234);
  test_varargs_macros ();

  // Check flexible array members.
  struct incomplete_array *ia =
    malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
  ia->datasize = 10;
  for (int i = 0; i < ia->datasize; ++i)
    ia->data[i] = i * 1.234;

  // Check named initializers.
  struct named_init ni = {
    .number = 34,
    .name = L"Test wide string",
    .average = 543.34343,
  };

  ni.number = 58;

  int dynamic_array[ni.number];
  dynamic_array[0] = argv[0][0];
  dynamic_array[ni.number - 1] = 543;

  // work around unused variable warnings
  ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\''
	 || dynamic_array[ni.number - 1] != 543);
'

# Test code for whether the C compiler supports C11 (global declarations)
ac_c_conftest_c11_globals='
// Does the compiler advertise C11 conformance?
#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L
# error "Compiler does not advertise C11 conformance"
#endif

// Check _Alignas.
char _Alignas (double) aligned_as_double;
char _Alignas (0) no_special_alignment;
extern char aligned_as_int;
char _Alignas (0) _Alignas (int) aligned_as_int;

// Check _Alignof.
enum
{
  int_alignment = _Alignof (int),
  int_array_alignment = _Alignof (int[100]),
  char_alignment = _Alignof (char)
};
_Static_assert (0 < -_Alignof (int), "_Alignof is signed");

// Check _Noreturn.
int _Noreturn does_not_return (void) { for (;;) continue; }

// Check _Static_assert.
struct test_static_assert
{
  int x;
  _Static_assert (sizeof (int) <= sizeof (long int),
                  "_Static_assert does not work in struct");
  long int y;
};

// Check UTF-8 literals.
#define u8 syntax error!
char const utf8_literal[] = u8"happens to be ASCII" "another string";

// Check duplicate typedefs.
typedef long *long_ptr;
typedef long int *long_ptr;
typedef long_ptr long_ptr;

// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1.
struct anonymous
{
  union {
    struct { int i; int j; };
    struct { int k; long int l; } w;
  };
  int m;
} v1;
'

# Test code for whether the C compiler supports C11 (body of main).
ac_c_conftest_c11_main='
  _Static_assert ((offsetof (struct anonymous, i)
		   == offsetof (struct anonymous, w.k)),
		  "Anonymous union alignment botch");
  v1.i = 2;
  v1.w.k = 5;
  ok |= v1.i != 5;
'

# Test code for whether the C compiler supports C11 (complete).
ac_c_conftest_c11_program="${ac_c_conftest_c89_globals}
${ac_c_conftest_c99_globals}
${ac_c_conftest_c11_globals}

int
main (int argc, char **argv)
{
  int ok = 0;
  ${ac_c_conftest_c89_main}
  ${ac_c_conftest_c99_main}
  ${ac_c_conftest_c11_main}
  return ok;
}
"

# Test code for whether the C compiler supports C99 (complete).
ac_c_conftest_c99_program="${ac_c_conftest_c89_globals}
${ac_c_conftest_c99_globals}

int
main (int argc, char **argv)
{
  int ok = 0;
  ${ac_c_conftest_c89_main}
  ${ac_c_conftest_c99_main}
  return ok;
}
"

# Test code for whether the C compiler supports C89 (complete).
ac_c_conftest_c89_program="${ac_c_conftest_c89_globals}

int
main (int argc, char **argv)
{
  int ok = 0;
  ${ac_c_conftest_c89_main}
  return ok;
}
"

as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H"
as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H"
as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H"
as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H"
as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H"
as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H"
as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H"
as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H"
as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H"
# Check that the precious variables saved in the cache have kept the same
# value.
ac_cache_corrupted=false
for ac_var in $ac_precious_vars; do
  eval ac_old_set=\$ac_cv_env_${ac_var}_set
  eval ac_new_set=\$ac_env_${ac_var}_set
  eval ac_old_val=\$ac_cv_env_${ac_var}_value
  eval ac_new_val=\$ac_env_${ac_var}_value
  case $ac_old_set,$ac_new_set in
    set,)
      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
printf "%s\n" "$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;}
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
printf "%s\n" "$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;}
	  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
printf "%s\n" "$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;}
	  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
printf "%s\n" "$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;}
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
printf "%s\n" "$as_me:   former value:  \`$ac_old_val'" >&2;}
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
printf "%s\n" "$as_me:   current value: \`$ac_new_val'" >&2;}
      fi;;
  esac
  # Pass precious variables to config.status.
  if test "$ac_new_set" = set; then
    case $ac_new_val in
    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
    *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
    *) ac_arg=$ac_var=$ac_new_val ;;
    esac
    case " $ac_configure_args " in
      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
    esac
  fi
done
if $ac_cache_corrupted; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;}
  as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file'
	    and start over" "$LINENO" 5
fi
## -------------------- ##
## Main body of script. ##
## -------------------- ##

ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu





# The following define is needed when building with Cygwin since newer
# versions of autoconf incorrectly set SHELL to /bin/bash instead of
# /bin/sh. The bash shell seems to suffer from some strange failures.
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
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







+
+
+
+
+
+
+
+
+









-
-
-
-
-
+
+
+
+
+
+







+
-
+
+
+
+

-
+

-
+










-
-
+
+

-
-
+
+








-
-
-
-
-
+
+
+
+
+
+







+
-
+
+
+
+

-
+

-
+










-
-
+
+

-
-
+
+







-
-
+
+












-
-
-
-
-
+
+
+
+
+
+







+
-
+
+
+
+

-
+

-
+










-
-
+
+

-
-
+
+








-
-
-
-
-
+
+
+
+
+
+








+
-
+
+
+
+

-
-
+
+




-
+















-
+






-
-
+
+

-
-
+
+










-
-
-
-
-
+
+
+
+
+
+







+
-
+
+
+
+

-
+

-
+










-
-
+
+

-
-
+
+












-
-
-
-
-
+
+
+
+
+
+







+
-
+
+
+
+

-
+

-
+










-
-
+
+

-
-
+
+











-
-
+
+




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





-
-
+
+




-
+


-
+






-
+









-
+







-
+











-
-
-
+
+
+




















-
+


-
-
+
+
+
















-
+















-
+


-
-
-
-
+
+
+
+
+


-
-
+
+


-
-
-
+
+
+

-
-
-
-
+
+
+
+




-
-
+
+






-
+


-
-
+
+
+













-
-
-
+
+
+




-
-
+
+








-
+











-
-
+
+







-
+


-
+







-
+


-
+






-
-
-
+
+
+





-
-
+
+



-
-
-
-
-
+
+
+
+
+
+




-
+













-
+


-
-
+
+
+








-
-
+
+


-
-
+
+





-
-
+
+


-
-
-
-
-
+
+
+
+
+
+




-
+









-
+
+

-
+


-
+



-
-
+
+
+
+





-
+

-
-
-
-
-
+
+
+
+
+
+








-
+






-
+
+

-
+





-
+






-
+
+

-
+






-
+






-
+
+


-
+

-
+

-
+


-
-
-
+
+
+














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




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





-
+
+


-
+







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

-
+
+
+
+
+
+
+
+
+
+










-
-
-
-
-
+
+
+
+
+
+






-
-
+
+



-
+
+


-
+




-
-
+
+
















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

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

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

-
-
-
-
-
-
-
-
-
-
-

-
-
-
-
-


-
-
-
-
-
-
-
-
-
-
-

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

-
+
-
-
-
-
-
+
-
-
-

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


-




-
-
-
-
-
+
+
+
+
+
+







+
-
+
+
+
+

-
+

-
+










-
-
+
+

-
-
+
+








-
-
-
-
-
+
+
+
+
+
+







+
-
+
+
+
+

-
+

-
+










-
-
+
+

-
-
+
+







-
-
+
+











-
-
-
-
-
+
+
+
+
+
+







+
-
+
+
+
+

-
+

-
+










-
-
+
+

-
-
+
+








-
-
-
-
-
+
+
+
+
+
+







+
-
+
+
+
+

-
+

-
+










-
-
+
+

-
-
+
+







-
-
+
+











-
-
-
-
-
+
+
+
+
+
+







+
-
+
+
+
+

-
+

-
+










-
-
+
+

-
-
+
+








-
-
-
-
-
+
+
+
+
+
+







+
-
+
+
+
+

-
+

-
+










-
-
+
+

-
-
+
+







-
-
+
+













-
-
+
+

-
-
-
-
+
+
+
+
+















-
-
+
+


-
-
+
+

















-
-
+
+

-
+
+

-
+



-
-
-
-
-
-
-
-

-
-
+
+


-
-
+
+


-
+







#------------------------------------------------------------------------

# 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_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
if test -n "$ac_tool_prefix"; then
  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
set dummy ${ac_tool_prefix}gcc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CC+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_CC+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_CC="${ac_tool_prefix}gcc"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
$as_echo "$CC" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
printf "%s\n" "$CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi


fi
if test -z "$ac_cv_prog_CC"; then
  ac_ct_CC=$CC
  # Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_CC+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_ac_ct_CC+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_CC="gcc"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
$as_echo "$ac_ct_CC" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
printf "%s\n" "$ac_ct_CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "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;}
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    CC=$ac_ct_CC
  fi
else
  CC="$ac_cv_prog_CC"
fi

if test -z "$CC"; then
          if test -n "$ac_tool_prefix"; then
    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
set dummy ${ac_tool_prefix}cc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CC+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_CC+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_CC="${ac_tool_prefix}cc"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
$as_echo "$CC" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
printf "%s\n" "$CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi


  fi
fi
if test -z "$CC"; then
  # Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CC+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_CC+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
       ac_prog_rejected=yes
       continue
     fi
    ac_cv_prog_CC="cc"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

if test $ac_prog_rejected = yes; then
  # We found a bogon in the path, so make sure we never use it.
  set dummy $ac_cv_prog_CC
  shift
  if test $# != 0; then
    # We chose a different compiler from the bogus one.
    # However, it has the same basename, so the bogon will be chosen
    # first if we set CC to just the basename; use the full file name.
    shift
    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
    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; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
printf "%s\n" "$CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi


fi
if test -z "$CC"; then
  if test -n "$ac_tool_prefix"; then
  for ac_prog in cl.exe
  do
    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CC+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_CC+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
$as_echo "$CC" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
printf "%s\n" "$CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi


    test -n "$CC" && break
  done
fi
if test -z "$CC"; then
  ac_ct_CC=$CC
  for ac_prog in cl.exe
do
  # Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_CC+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_ac_ct_CC+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_CC="$ac_prog"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
$as_echo "$ac_ct_CC" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
printf "%s\n" "$ac_ct_CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "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;}
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    CC=$ac_ct_CC
  fi
fi

fi
if test -z "$CC"; then
  if test -n "$ac_tool_prefix"; then
  # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args.
set dummy ${ac_tool_prefix}clang; ac_word=$2
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_CC+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_CC="${ac_tool_prefix}clang"
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
printf "%s\n" "$CC" >&6; }
else
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi


fi
if test -z "$ac_cv_prog_CC"; then
  ac_ct_CC=$CC
  # Extract the first word of "clang", so it can be a program name with args.
set dummy clang; ac_word=$2
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_ac_ct_CC+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_CC="clang"
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
printf "%s\n" "$ac_ct_CC" >&6; }
else
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi

  if test "x$ac_ct_CC" = x; then
    CC=""
  else
    case $cross_compiling:$ac_tool_warned in
yes:)
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    CC=$ac_ct_CC
  fi
else
  CC="$ac_cv_prog_CC"
fi

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;}
test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "no acceptable C compiler found in \$PATH
See \`config.log' for more details" "$LINENO" 5; }

# Provide some information about the compiler.
$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
set X $ac_compile
ac_compiler=$2
for ac_option in --version -v -V -qversion; do
for ac_option in --version -v -V -qversion -version; 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
printf "%s\n" "$ac_try_echo"; } >&5
  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
  ac_status=$?
  if test -s conftest.err; then
    sed '10a\
... rest of stderr output deleted ...
         10q' conftest.err >conftest.er1
    cat conftest.er1 >&5
  fi
  rm -f conftest.er1 conftest.err
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }
done

cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
main (void)
{

  ;
  return 0;
}
_ACEOF
ac_clean_files_save=$ac_clean_files
ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
# Try to create an executable without -o first, disregard a.out.
# It will help us diagnose broken compilers, and finding out an intuition
# of exeext.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
$as_echo_n "checking whether the C compiler works... " >&6; }
ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
printf %s "checking whether the C compiler works... " >&6; }
ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'`

# The possible output files:
ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"

ac_rmfiles=
for ac_file in $ac_files
do
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
  esac
done
rm -f $ac_rmfiles

if { { ac_try="$ac_link_default"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
printf "%s\n" "$ac_try_echo"; } >&5
  (eval "$ac_link_default") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; then :
  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }
then :
  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
# in a Makefile.  We should not override ac_cv_exeext if it was cached,
# so that the user can short-circuit this test for compilers unknown to
# Autoconf.
for ac_file in $ac_files ''
do
  test -f "$ac_file" || continue
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
	;;
    [ab].out )
	# We found the default executable, but exeext='' is most
	# certainly right.
	break;;
    *.* )
	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
	if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no;
	then :; else
	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
	fi
	# We set ac_cv_exeext here because the later test for it is not
	# safe: cross compilers may not add the suffix if given an `-o'
	# argument, so we may need to know it at that point already.
	# Even if this section looks crufty: it has the advantage of
	# actually working.
	break;;
    * )
	break;;
  esac
done
test "$ac_cv_exeext" = no && ac_cv_exeext=

else
else $as_nop
  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
if test -z "$ac_file"
then :
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
printf "%s\n" "$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;}
{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
printf "%s\n" "$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; }
else $as_nop
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
$as_echo_n "checking for C compiler default output file name... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
$as_echo "$ac_file" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
printf %s "checking for C compiler default output file name... " >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
printf "%s\n" "$ac_file" >&6; }
ac_exeext=$ac_cv_exeext

rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
ac_clean_files=$ac_clean_files_save
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
$as_echo_n "checking for suffix of executables... " >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
printf %s "checking for suffix of executables... " >&6; }
if { { ac_try="$ac_link"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
printf "%s\n" "$ac_try_echo"; } >&5
  (eval "$ac_link") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; then :
  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }
then :
  # If both `conftest.exe' and `conftest' are `present' (well, observable)
# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
# work properly (i.e., refer to `conftest.exe'), while it won't with
# `rm'.
for ac_file in conftest.exe conftest conftest.*; do
  test -f "$ac_file" || continue
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
	  break;;
    * ) break;;
  esac
done
else
  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
else $as_nop
  { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of executables: cannot compile and link
See \`config.log' for more details" "$LINENO" 5; }
fi
rm -f conftest conftest$ac_cv_exeext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
$as_echo "$ac_cv_exeext" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
printf "%s\n" "$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 ()
main (void)
{
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; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
printf %s "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
printf "%s\n" "$ac_try_echo"; } >&5
  (eval "$ac_link") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  printf "%s\n" "$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
printf "%s\n" "$ac_try_echo"; } >&5
  (eval "$ac_try") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  printf "%s\n" "$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.
	{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error 77 "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; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
printf "%s\n" "$cross_compiling" >&6; }

rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
ac_clean_files=$ac_clean_files_save
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
$as_echo_n "checking for suffix of object files... " >&6; }
if ${ac_cv_objext+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
printf %s "checking for suffix of object files... " >&6; }
if test ${ac_cv_objext+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
main (void)
{

  ;
  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
printf "%s\n" "$ac_try_echo"; } >&5
  (eval "$ac_compile") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; then :
  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }
then :
  for ac_file in conftest.o conftest.obj conftest.*; do
  test -f "$ac_file" || continue;
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
       break;;
  esac
done
else
  $as_echo "$as_me: failed program was:" >&5
else $as_nop
  printf "%s\n" "$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;}
{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of object files: cannot compile
See \`config.log' for more details" "$LINENO" 5; }
fi
rm -f conftest.$ac_cv_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
$as_echo "$ac_cv_objext" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
printf "%s\n" "$ac_cv_objext" >&6; }
OBJEXT=$ac_cv_objext
ac_objext=$OBJEXT
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
if ${ac_cv_c_compiler_gnu+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5
printf %s "checking whether the compiler supports GNU C... " >&6; }
if test ${ac_cv_c_compiler_gnu+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
main (void)
{
#ifndef __GNUC__
       choke me
#endif

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  ac_compiler_gnu=yes
else
else $as_nop
  ac_compiler_gnu=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam 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; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; }
ac_compiler_gnu=$ac_cv_c_compiler_gnu

if test $ac_compiler_gnu = yes; then
  GCC=yes
else
  GCC=
fi
ac_test_CFLAGS=${CFLAGS+set}
ac_test_CFLAGS=${CFLAGS+y}
ac_save_CFLAGS=$CFLAGS
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
$as_echo_n "checking whether $CC accepts -g... " >&6; }
if ${ac_cv_prog_cc_g+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
printf %s "checking whether $CC accepts -g... " >&6; }
if test ${ac_cv_prog_cc_g+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  ac_save_c_werror_flag=$ac_c_werror_flag
   ac_c_werror_flag=yes
   ac_cv_prog_cc_g=no
   CFLAGS="-g"
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_prog_cc_g=yes
else
else $as_nop
  CFLAGS=""
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :

else
else $as_nop
  ac_c_werror_flag=$ac_save_c_werror_flag
	 CFLAGS="-g"
	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_prog_cc_g=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   ac_c_werror_flag=$ac_save_c_werror_flag
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
$as_echo "$ac_cv_prog_cc_g" >&6; }
if test "$ac_test_CFLAGS" = set; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
printf "%s\n" "$ac_cv_prog_cc_g" >&6; }
if test $ac_test_CFLAGS; then
  CFLAGS=$ac_save_CFLAGS
elif test $ac_cv_prog_cc_g = yes; then
  if test "$GCC" = yes; then
    CFLAGS="-g -O2"
  else
    CFLAGS="-g"
  fi
else
  if test "$GCC" = yes; then
    CFLAGS="-O2"
  else
    CFLAGS=
  fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
if ${ac_cv_prog_cc_c89+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5
printf %s "checking for $CC option to enable C11 features... " >&6; }
if test ${ac_cv_prog_cc_c11+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  ac_cv_prog_cc_c11=no
ac_save_CC=$CC
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$ac_c_conftest_c11_program
_ACEOF
for ac_arg in '' -std=gnu11
do
  CC="$ac_save_CC $ac_arg"
  if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_prog_cc_c11=$ac_arg
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam
  test "x$ac_cv_prog_cc_c11" != "xno" && break
done
rm -f conftest.$ac_ext
CC=$ac_save_CC

fi
# AC_CACHE_VAL
ac_prog_cc_stdc_options=
case "x$ac_cv_prog_cc_c11" in #(
  x) :
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
printf "%s\n" "none needed" >&6; } ;; #(
  xno) :
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
printf "%s\n" "unsupported" >&6; } ;; #(
  *) :
    ac_prog_cc_stdc_options=" $ac_cv_prog_cc_c11"
    CC="$CC$ac_prog_cc_stdc_options"
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5
printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } ;;
esac
if test "x$ac_cv_prog_cc_c11" != xno
then :
  ac_prog_cc_stdc=c11
		 ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11
else $as_nop
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5
printf %s "checking for $CC option to enable C99 features... " >&6; }
if test ${ac_cv_prog_cc_c99+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  ac_cv_prog_cc_c99=no
ac_save_CC=$CC
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$ac_c_conftest_c89_program
_ACEOF
for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc1x -qlanglvl=extc99
do
  CC="$ac_save_CC $ac_arg"
  if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_prog_cc_c99=$ac_arg
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam
  test "x$ac_cv_prog_cc_c99" != "xno" && break
done
rm -f conftest.$ac_ext
CC=$ac_save_CC

fi
# AC_CACHE_VAL
ac_prog_cc_stdc_options=
case "x$ac_cv_prog_cc_c99" in #(
  x) :
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
printf "%s\n" "none needed" >&6; } ;; #(
  xno) :
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
printf "%s\n" "unsupported" >&6; } ;; #(
  *) :
    ac_prog_cc_stdc_options=" $ac_cv_prog_cc_c99"
    CC="$CC$ac_prog_cc_stdc_options"
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } ;;
esac
if test "x$ac_cv_prog_cc_c99" != xno
then :
  ac_prog_cc_stdc=c99
		    ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
else $as_nop
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5
printf %s "checking for $CC option to enable C89 features... " >&6; }
if test ${ac_cv_prog_cc_c89+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  ac_cv_prog_cc_c89=no
ac_save_CC=$CC
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <stdarg.h>
#include <stdio.h>
struct stat;
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
struct buf { int x; };
FILE * (*rcsopen) (struct buf *, struct stat *, int);
static char *e (p, i)
     char **p;
     int i;
{
  return p[i];
}
static char *f (char * (*g) (char **, int), char **p, ...)
{
  char *s;
  va_list v;
  va_start (v,p);
  s = g (p, va_arg (v,int));
  va_end (v);
  return s;
}

$ac_c_conftest_c89_program
/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
   function prototypes and stuff, but not '\xHH' hex character constants.
   These don't provoke an error unfortunately, instead are silently treated
   as 'x'.  The following induces an error, until -std is added to get
   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
   array size at least.  It's necessary to write '\x00'==0 to get something
   that's true only with -std.  */
int osf4_cc_array ['\x00' == 0 ? 1 : -1];

/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
   inside strings and character constants.  */
#define FOO(x) 'x'
int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];

int test (int i, double x);
struct s1 {int (*f) (int a);};
struct s2 {int (*f) (double a);};
int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
int argc;
char **argv;
int
main ()
{
return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
  ;
  return 0;
}
_ACEOF
for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
do
  CC="$ac_save_CC $ac_arg"
  if ac_fn_c_try_compile "$LINENO"; then :
  if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_prog_cc_c89=$ac_arg
fi
rm -f core conftest.err conftest.$ac_objext
rm -f core conftest.err conftest.$ac_objext conftest.beam
  test "x$ac_cv_prog_cc_c89" != "xno" && break
done
rm -f conftest.$ac_ext
CC=$ac_save_CC

fi
# AC_CACHE_VAL
ac_prog_cc_stdc_options=
case "x$ac_cv_prog_cc_c89" in
  x)
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
$as_echo "none needed" >&6; } ;;
  xno)
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
$as_echo "unsupported" >&6; } ;;
  *)
    CC="$CC $ac_cv_prog_cc_c89"
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
case "x$ac_cv_prog_cc_c89" in #(
  x) :
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
printf "%s\n" "none needed" >&6; } ;; #(
  xno) :
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
printf "%s\n" "unsupported" >&6; } ;; #(
  *) :
    ac_prog_cc_stdc_options=" $ac_cv_prog_cc_c89"
    CC="$CC$ac_prog_cc_stdc_options"
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } ;;
esac
if test "x$ac_cv_prog_cc_c89" != xno; then :
if test "x$ac_cv_prog_cc_c89" != xno
then :
  ac_prog_cc_stdc=c89
		       ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
else $as_nop
  ac_prog_cc_stdc=no
		       ac_cv_prog_cc_stdc=no
fi

fi

fi

ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
$as_echo_n "checking for inline... " >&6; }
if ${ac_cv_c_inline+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
printf %s "checking for inline... " >&6; }
if test ${ac_cv_c_inline+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  ac_cv_c_inline=no
for ac_kw in inline __inline__ __inline; do
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#ifndef __cplusplus
typedef int foo_t;
static $ac_kw foo_t static_foo () {return 0; }
$ac_kw foo_t foo () {return 0; }
static $ac_kw foo_t static_foo (void) {return 0; }
$ac_kw foo_t foo (void) {return 0; }
#endif

_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_c_inline=$ac_kw
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam 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; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
printf "%s\n" "$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;;
    esac
    cat >>confdefs.h <<_ACEOF
#ifndef __cplusplus
#define inline $ac_val
#endif
_ACEOF
    ;;
esac

ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
$as_echo_n "checking how to run the C preprocessor... " >&6; }
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
  CPP=
fi
if test -z "$CPP"; then
  if ${ac_cv_prog_CPP+:} false; then :
  $as_echo_n "(cached) " >&6
else
      # Double quotes because CPP needs to be expanded
    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
    do
      ac_preproc_ok=false
for ac_c_preproc_warn_flag in '' yes
do
  # Use a header file that comes with gcc, so configuring glibc
  # with a fresh cross-compiler works.
  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
  # <limits.h> exists even on freestanding compilers.
  # On the NeXT, cc -E runs the code through the compiler's parser,
  # not just through cpp. "Syntax error" is here to catch this case.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
		     Syntax error
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :

ac_header= ac_cache=
else
  # Broken: fails on valid input.
continue
fi
rm -f conftest.err conftest.i conftest.$ac_ext

for ac_item in $ac_header_c_list
  # OK, works on sane cases.  Now check whether nonexistent headers
  # can be detected and how.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <ac_nonexistent.h>
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :
  # Broken: success on invalid input.
continue
else
  # Passes both tests.
ac_preproc_ok=:
break
fi
rm -f conftest.err conftest.i conftest.$ac_ext

done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
rm -f conftest.i conftest.err conftest.$ac_ext
if $ac_preproc_ok; then :
  break
fi

    done
    ac_cv_prog_CPP=$CPP

fi
  CPP=$ac_cv_prog_CPP
else
  ac_cv_prog_CPP=$CPP
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
$as_echo "$CPP" >&6; }
ac_preproc_ok=false
for ac_c_preproc_warn_flag in '' yes
do
  # Use a header file that comes with gcc, so configuring glibc
  # with a fresh cross-compiler works.
  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
  # <limits.h> exists even on freestanding compilers.
  # On the NeXT, cc -E runs the code through the compiler's parser,
  # not just through cpp. "Syntax error" is here to catch this case.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
		     Syntax error
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :

  if test $ac_cache; then
else
  # Broken: fails on valid input.
continue
fi
rm -f conftest.err conftest.i conftest.$ac_ext

    ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default"
  # OK, works on sane cases.  Now check whether nonexistent headers
  # can be detected and how.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <ac_nonexistent.h>
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :
  # Broken: success on invalid input.
continue
else
  # Passes both tests.
ac_preproc_ok=:
break
fi
rm -f conftest.err conftest.i conftest.$ac_ext

    if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then
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 :

      printf "%s\n" "#define $ac_item 1" >> confdefs.h
else
  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
See \`config.log' for more details" "$LINENO" 5; }
fi

    fi
    ac_header= ac_cache=
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


  elif test $ac_header; then
    ac_cache=$ac_item
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
if ${ac_cv_path_GREP+:} false; then :
  $as_echo_n "(cached) " >&6
else
  else
  if test -z "$GREP"; then
  ac_path_GREP_found=false
  # Loop through the user's path and test for each of PROGNAME-LIST
  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_prog in grep ggrep; do
    for ac_exec_ext in '' $ac_executable_extensions; do
      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
      as_fn_executable_p "$ac_path_GREP" || continue
# Check for GNU ac_path_GREP and select it if it is found.
  # Check for GNU $ac_path_GREP
case `"$ac_path_GREP" --version 2>&1` in
*GNU*)
  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
*)
  ac_count=0
  $as_echo_n 0123456789 >"conftest.in"
  while :
  do
    cat "conftest.in" "conftest.in" >"conftest.tmp"
    mv "conftest.tmp" "conftest.in"
    cp "conftest.in" "conftest.nl"
    $as_echo 'GREP' >> "conftest.nl"
    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
    as_fn_arith $ac_count + 1 && ac_count=$as_val
    if test $ac_count -gt ${ac_path_GREP_max-0}; then
      # Best one so far, save it but keep looking for a better one
      ac_cv_path_GREP="$ac_path_GREP"
      ac_path_GREP_max=$ac_count
    fi
    # 10*(2^10) chars as input seems more than enough
    test $ac_count -gt 10 && break
  done
  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
esac

    ac_header=$ac_item
      $ac_path_GREP_found && break 3
    done
  done
  done
IFS=$as_save_IFS
  if test -z "$ac_cv_path_GREP"; then
    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
  fi
else
  ac_cv_path_GREP=$GREP
fi

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
$as_echo "$ac_cv_path_GREP" >&6; }
 GREP="$ac_cv_path_GREP"


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
$as_echo_n "checking for egrep... " >&6; }
if ${ac_cv_path_EGREP+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
   then ac_cv_path_EGREP="$GREP -E"
   else
     if test -z "$EGREP"; then
  ac_path_EGREP_found=false
  # Loop through the user's path and test for each of PROGNAME-LIST
  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_prog in egrep; do
    for ac_exec_ext in '' $ac_executable_extensions; do
      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
      as_fn_executable_p "$ac_path_EGREP" || continue
# Check for GNU ac_path_EGREP and select it if it is found.
  # Check for GNU $ac_path_EGREP
case `"$ac_path_EGREP" --version 2>&1` in
*GNU*)
  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
*)
  ac_count=0
  $as_echo_n 0123456789 >"conftest.in"
  while :
  do
    cat "conftest.in" "conftest.in" >"conftest.tmp"
    mv "conftest.tmp" "conftest.in"
    cp "conftest.in" "conftest.nl"
    $as_echo 'EGREP' >> "conftest.nl"
    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
    as_fn_arith $ac_count + 1 && ac_count=$as_val
    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
      # Best one so far, save it but keep looking for a better one
      ac_cv_path_EGREP="$ac_path_EGREP"
      ac_path_EGREP_max=$ac_count
    fi
    # 10*(2^10) chars as input seems more than enough
    test $ac_count -gt 10 && break
  done
done
  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
esac

      $ac_path_EGREP_found && break 3
    done
  done
  done
IFS=$as_save_IFS
  if test -z "$ac_cv_path_EGREP"; then
    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
  fi
else
  ac_cv_path_EGREP=$EGREP
fi

   fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
$as_echo "$ac_cv_path_EGREP" >&6; }
 EGREP="$ac_cv_path_EGREP"


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
$as_echo_n "checking for ANSI C header files... " >&6; }
if ${ac_cv_header_stdc+:} false; then :
  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <float.h>

int
main ()
{


  ;
  return 0;
}

_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
  ac_cv_header_stdc=yes
else
  ac_cv_header_stdc=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

if test $ac_cv_header_stdc = yes; then
if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes
  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <string.h>

then :
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  $EGREP "memchr" >/dev/null 2>&1; then :

else
  ac_cv_header_stdc=no
fi
rm -f conftest*

fi

if test $ac_cv_header_stdc = yes; then
  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <stdlib.h>

_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  $EGREP "free" >/dev/null 2>&1; then :

else
  ac_cv_header_stdc=no
fi
rm -f conftest*

fi

if test $ac_cv_header_stdc = yes; then
  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
  if test "$cross_compiling" = yes; then :
  :
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <ctype.h>
#include <stdlib.h>
#if ((' ' & 0x0FF) == 0x020)
# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
#else
# define ISLOWER(c) \
		   (('a' <= (c) && (c) <= 'i') \
		     || ('j' <= (c) && (c) <= 'r') \
		     || ('s' <= (c) && (c) <= 'z'))
# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
#endif

#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
int
main ()
{
  int i;
  for (i = 0; i < 256; i++)
    if (XOR (islower (i), ISLOWER (i))
	|| toupper (i) != TOUPPER (i))
      return 2;
  return 0;
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :

else
  ac_cv_header_stdc=no
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
  conftest.$ac_objext conftest.beam conftest.$ac_ext
fi

fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
$as_echo "$ac_cv_header_stdc" >&6; }
if test $ac_cv_header_stdc = yes; then

$as_echo "#define STDC_HEADERS 1" >>confdefs.h
printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h

fi


if test -n "$ac_tool_prefix"; then
  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
set dummy ${ac_tool_prefix}ar; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_AR+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_AR+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_AR="${ac_tool_prefix}ar"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
AR=$ac_cv_prog_AR
if test -n "$AR"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
$as_echo "$AR" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
printf "%s\n" "$AR" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi


fi
if test -z "$ac_cv_prog_AR"; then
  ac_ct_AR=$AR
  # Extract the first word of "ar", so it can be a program name with args.
set dummy ar; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_AR+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_ac_ct_AR+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_AR="ar"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
ac_ct_AR=$ac_cv_prog_ac_ct_AR
if test -n "$ac_ct_AR"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
$as_echo "$ac_ct_AR" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
printf "%s\n" "$ac_ct_AR" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "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;}
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    AR=$ac_ct_AR
  fi
else
  AR="$ac_cv_prog_AR"
fi

if test -n "$ac_tool_prefix"; then
  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
set dummy ${ac_tool_prefix}ranlib; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_RANLIB+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_RANLIB+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
RANLIB=$ac_cv_prog_RANLIB
if test -n "$RANLIB"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
$as_echo "$RANLIB" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
printf "%s\n" "$RANLIB" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi


fi
if test -z "$ac_cv_prog_RANLIB"; then
  ac_ct_RANLIB=$RANLIB
  # Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_ac_ct_RANLIB+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_RANLIB="ranlib"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
if test -n "$ac_ct_RANLIB"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
$as_echo "$ac_ct_RANLIB" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
printf "%s\n" "$ac_ct_RANLIB" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "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;}
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    RANLIB=$ac_ct_RANLIB
  fi
else
  RANLIB="$ac_cv_prog_RANLIB"
fi

if test -n "$ac_tool_prefix"; then
  # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args.
set dummy ${ac_tool_prefix}windres; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_RC+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_RC+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_RC="${ac_tool_prefix}windres"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
RC=$ac_cv_prog_RC
if test -n "$RC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RC" >&5
$as_echo "$RC" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RC" >&5
printf "%s\n" "$RC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi


fi
if test -z "$ac_cv_prog_RC"; then
  ac_ct_RC=$RC
  # Extract the first word of "windres", so it can be a program name with args.
set dummy windres; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_RC+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_ac_ct_RC+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_RC="windres"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
ac_ct_RC=$ac_cv_prog_ac_ct_RC
if test -n "$ac_ct_RC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RC" >&5
$as_echo "$ac_ct_RC" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RC" >&5
printf "%s\n" "$ac_ct_RC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "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;}
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    RC=$ac_ct_RC
  fi
else
  RC="$ac_cv_prog_RC"
fi


#--------------------------------------------------------------------
# Checks to see if the make program sets the $MAKE variable.
#--------------------------------------------------------------------

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
set x ${MAKE-make}
ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
  $as_echo_n "(cached) " >&6
else
ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
if eval test \${ac_cv_prog_make_${ac_make}_set+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
  SET_MAKE=
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
  SET_MAKE="MAKE=${MAKE-make}"
fi


#--------------------------------------------------------------------
# Determines the correct binary file extension (.o, .obj, .exe etc.)
#--------------------------------------------------------------------




#--------------------------------------------------------------------
# The statements below define a collection of symbols related to
# building libtk as a shared library instead of a static library.
#--------------------------------------------------------------------


    { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to build libraries" >&5
$as_echo_n "checking how to build libraries... " >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to build libraries" >&5
printf %s "checking how to build libraries... " >&6; }
    # Check whether --enable-shared was given.
if test "${enable_shared+set}" = set; then :
if test ${enable_shared+y}
then :
  enableval=$enable_shared; tcl_ok=$enableval
else
else $as_nop
  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; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: shared" >&5
printf "%s\n" "shared" >&6; }
	SHARED_BUILD=1
    else
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
$as_echo "static" >&6; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: static" >&5
printf "%s\n" "static" >&6; }
	SHARED_BUILD=0

$as_echo "#define STATIC_BUILD 1" >>confdefs.h
printf "%s\n" "#define STATIC_BUILD 1" >>confdefs.h

    fi



#--------------------------------------------------------------------
# Locate and source the tclConfig.sh file.
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
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







-
+
+



-
-
-
-
-
+
+
+
+
+
+







-
-
+
+







    #

    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 :
if test ${with_tcl+y}
then :
  withval=$with_tcl; with_tclconfig="${withval}"
fi

	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl configuration" >&5
$as_echo_n "checking for Tcl configuration... " >&6; }
	if ${ac_cv_c_tclconfig+:} false; then :
  $as_echo_n "(cached) " >&6
else
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Tcl configuration" >&5
printf %s "checking for Tcl configuration... " >&6; }
	if test ${ac_cv_c_tclconfig+y}
then :
  printf %s "(cached) " >&6
else $as_nop


	    # 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;}
			    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5
printf "%s\n" "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;}
			    with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
			fi ;;
		esac
		if test -f "${with_tclconfig}/tclConfig.sh" ; then
		    ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
		else
		    as_fn_error $? "${with_tclconfig} directory doesn't contain tclConfig.sh" "$LINENO" 5
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
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







-
-
+
+




-
-
+
+


-
-
+
+


-
-
+
+

















-
-
-
-
-
-
-
-
-








	if test x"${ac_cv_c_tclconfig}" = x ; then
	    TCL_BIN_DIR="# no Tcl configs found"
	    as_fn_error $? "Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh" "$LINENO" 5
	else
	    no_tcl=
	    TCL_BIN_DIR="${ac_cv_c_tclconfig}"
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5
$as_echo "found ${TCL_BIN_DIR}/tclConfig.sh" >&6; }
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5
printf "%s\n" "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; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for existence of ${TCL_BIN_DIR}/tclConfig.sh" >&5
printf %s "checking for existence of ${TCL_BIN_DIR}/tclConfig.sh... " >&6; }

    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5
$as_echo "loading" >&6; }
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: loading" >&5
printf "%s\n" "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; }
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: could not find ${TCL_BIN_DIR}/tclConfig.sh" >&5
printf "%s\n" "could not find ${TCL_BIN_DIR}/tclConfig.sh" >&6; }
    fi

    #
    # If the TCL_BIN_DIR is the build directory (not the install directory),
    # then set the common variable name to the value of the build variables.
    # For example, the variable TCL_LIB_SPEC will be set to the value
    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
    # installed and uninstalled version of Tcl.
    #

    if test -f $TCL_BIN_DIR/Makefile ; then
        TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
        TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
        TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
    fi

    #
    # eval is required to do the TCL_DBGX substitution
    #

    eval "TCL_ZIP_FILE=\"${TCL_ZIP_FILE}\""
    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}\""




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







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





-
-
+
+

-
+
+

-
+



-
-
+
+




-
+




-
-
-
-
-
+
+
+
+
+
+







+
-
+
+
+
+

-
+

-
+











-
-
+
+

-
-
+
+





-
-
-
-
-
+
+
+
+
+
+







+
-
+
+
+
+

-
+

-
+










-
-
+
+

-
-
+
+












-
-
-
-
-
+
+
+
+
+
+








-
+






-
+
+

-
+


-
+


-
-
+
+







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; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if 64bit support is requested" >&5
printf %s "checking if 64bit support is requested... " >&6; }
    # Check whether --enable-64bit was given.
if test "${enable_64bit+set}" = set; then :
if test ${enable_64bit+y}
then :
  enableval=$enable_64bit; do64bit=$enableval
else
else $as_nop
  do64bit=no
fi

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bit" >&5
$as_echo "$do64bit" >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $do64bit" >&5
printf "%s\n" "$do64bit" >&6; }

    # Set some defaults (may get changed below)
    EXTRA_CFLAGS=""

$as_echo "#define MODULE_SCOPE extern" >>confdefs.h
printf "%s\n" "#define MODULE_SCOPE extern" >>confdefs.h


    # Extract the first word of "cygpath", so it can be a program name with args.
set dummy cygpath; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CYGPATH+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_CYGPATH+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
    ac_cv_prog_CYGPATH="cygpath -m"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

  test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo"
fi
fi
CYGPATH=$ac_cv_prog_CYGPATH
if test -n "$CYGPATH"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CYGPATH" >&5
$as_echo "$CYGPATH" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CYGPATH" >&5
printf "%s\n" "$CYGPATH" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi


    # Extract the first word of "wine", so it can be a program name with args.
set dummy wine; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_WINE+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_prog_WINE+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  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
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi
fi
WINE=$ac_cv_prog_WINE
if test -n "$WINE"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WINE" >&5
$as_echo "$WINE" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $WINE" >&5
printf "%s\n" "$WINE" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi



    SHLIB_SUFFIX=".dll"

    # MACHINE is IX86 for LINK, but this is used by the manifest,
    # which requires x86|amd64|ia64.
    MACHINE="X86"

    if test "$GCC" = "yes"; then

      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cross-compile version of gcc" >&5
$as_echo_n "checking for cross-compile version of gcc... " >&6; }
if ${ac_cv_cross+:} false; then :
  $as_echo_n "(cached) " >&6
else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for cross-compile version of gcc" >&5
printf %s "checking for cross-compile version of gcc... " >&6; }
if test ${ac_cv_cross+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

	    #ifndef _WIN32
		#error cross-compiler
	    #endif

int
main ()
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_cross=no
else
else $as_nop
  ac_cv_cross=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cross" >&5
$as_echo "$ac_cv_cross" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cross" >&5
printf "%s\n" "$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"
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
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







-
-
+
+





-
+

-
-
+
+

-
-
+
+

















-
-
-
-
-
+
+
+
+
+
+








-
+






-
+
+

-
+


-
+


-
-
+
+





-
-
-
-
-
+
+
+
+
+
+







-
+






-
+







-
+






+
-
+

-
-
+
+




















-
+






-
+
+

-
+


-
+



-
-
+
+






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

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




















-
-
+
+


-
+


-
-
+
+










-
+







-
+


-
-
-
+
+
+






-
+








-
+








    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; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Windows native path bug in windres" >&5
printf %s "checking for Windows native path bug in windres... " >&6; }
	cyg_conftest=`$CYGPATH $conftest`
	if { ac_try='$RC -o conftest.res.o $cyg_conftest'
  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  printf "%s\n" "$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; }
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
	else
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
	    CYGPATH=echo
	fi
	conftest=
	cyg_conftest=
    fi

    if test "$CYGPATH" = "echo"; then
        DEPARG='"$<"'
    else
        DEPARG='"$(shell $(CYGPATH) $<)"'
    fi

    # set various compiler flags depending on whether we are using gcc or cl

    if test "${GCC}" = "yes" ; then
	extra_cflags="-pipe"
	extra_ldflags="-pipe -static-libgcc"
	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for mingw32 version of gcc" >&5
$as_echo_n "checking for mingw32 version of gcc... " >&6; }
if ${ac_cv_win32+:} false; then :
  $as_echo_n "(cached) " >&6
else
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for mingw32 version of gcc" >&5
printf %s "checking for mingw32 version of gcc... " >&6; }
if test ${ac_cv_win32+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

		#ifdef _WIN32
		    #error win32
		#endif

int
main ()
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_win32=no
else
else $as_nop
  ac_cv_win32=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_win32" >&5
$as_echo "$ac_cv_win32" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_win32" >&5
printf "%s\n" "$ac_cv_win32" >&6; }
	if test "$ac_cv_win32" != "yes"; then
	    as_fn_error $? "${CC} cannot produce win32 executables." "$LINENO" 5
	fi

	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -mwindows -municode -Dmain=xxmain"
	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working -municode linker flag" >&5
$as_echo_n "checking for working -municode linker flag... " >&6; }
if ${ac_cv_municode+:} false; then :
  $as_echo_n "(cached) " >&6
else
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working -municode linker flag" >&5
printf %s "checking for working -municode linker flag... " >&6; }
if test ${ac_cv_municode+y}
then :
  printf %s "(cached) " >&6
else $as_nop

# 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
  rm -f conftest.$ac_objext conftest.beam 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
printf "%s\n" "$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
  printf "%s\n" "$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 :
then :
  ac_retval=0
else
  $as_echo "$as_me: failed program was:" >&5
else $as_nop
  printf "%s\n" "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

	ac_retval=1
fi
  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
  # interfere with the next link command; also delete a directory that is
  # left behind by Apple's compiler.  We do this before executing the actions.
  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
  as_fn_set_status $ac_retval

} # ac_fn_c_try_link
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

	#include <windows.h>
	int APIENTRY wWinMain(HINSTANCE a, HINSTANCE b, LPWSTR c, int d) {return 0;}

int
main ()
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_municode=yes
else
else $as_nop
  ac_cv_municode=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    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; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_municode" >&5
printf "%s\n" "$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
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working -fno-lto" >&5
printf %s "checking for working -fno-lto... " >&6; }
if test ${ac_cv_nolto+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_nolto=yes
else $as_nop
  ac_cv_nolto=no
    fi
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext

fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_nolto" >&5
printf "%s\n" "$ac_cv_nolto" >&6; }
	CFLAGS=$hold_cflags
	if test "$ac_cv_nolto" = "yes" ; then
	    CFLAGS_NOLTO="-fno-lto"
	else
	    CFLAGS_NOLTO=""
	fi
    fi

    { $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler flags" >&5
$as_echo_n "checking compiler flags... " >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking compiler flags" >&5
printf %s "checking compiler flags... " >&6; }
    if test "${GCC}" = "yes" ; then
	SHLIB_LD=""
	SHLIB_LD_LIBS='${LIBS}'
	LIBS="-lnetapi32 -lkernel32 -luser32 -ladvapi32 -luserenv -lws2_32"
	# mingw needs to link ole32 and oleaut32 for [send], but MSVC doesn't
	LIBS_GUI="-lgdi32 -lcomdlg32 -limm32 -lcomctl32 -lshell32 -luuid -lole32 -loleaut32"
	STLIB_LD='${AR} cr'
	RC_OUT=-o
	RC_TYPE=
	RC_INCLUDE=--include
	RC_DEFINE=--define
	RES=res.o
	MAKE_LIB="\${STLIB_LD} \$@"
	MAKE_STUB_LIB="\${STLIB_LD} \$@"
	POST_MAKE_LIB="\${RANLIB} \$@"
	MAKE_EXE="\${CC} -o \$@"
	LIBPREFIX="lib"

	if test "${SHARED_BUILD}" = "0" ; then
	    # static
            { $as_echo "$as_me:${as_lineno-$LINENO}: result: using static flags" >&5
$as_echo "using static flags" >&6; }
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: using static flags" >&5
printf "%s\n" "using static flags" >&6; }
	    runtime=
	    LIBRARIES="\${STATIC_LIBRARIES}"
	    EXESUFFIX="s\${DBGX}.exe"
	    EXESUFFIX="s.exe"
	else
	    # dynamic
            { $as_echo "$as_me:${as_lineno-$LINENO}: result: using shared flags" >&5
$as_echo "using shared flags" >&6; }
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: using shared flags" >&5
printf "%s\n" "using shared flags" >&6; }

	    # ad-hoc check to see if CC supports -shared.
	    if "${CC}" -shared 2>&1 | egrep ': -shared not supported' >/dev/null; then
		as_fn_error $? "${CC} does not support the -shared option.
                You will need to upgrade to a newer version of the toolchain." "$LINENO" 5
	    fi

	    runtime=
	    # Add SHLIB_LD_LIBS to the Make rule, not here.

	    EXESUFFIX="\${DBGX}.exe"
	    EXESUFFIX=".exe"
	    LIBRARIES="\${SHARED_LIBRARIES}"
	fi
	# Link with gcc since ld does not link to default libs like
	# -luser32 and -lmsvcrt by default.
	SHLIB_LD='${CC} -shared'
	SHLIB_LD_LIBS='${LIBS}'
	MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -o \$@ ${extra_ldflags} \
	    -Wl,--out-implib,\$(patsubst %.dll,lib%.a,\$@)"
	    -Wl,--out-implib,\$(patsubst %.dll,lib%.dll.a,\$@)"
	# DLLSUFFIX is separate because it is the building block for
	# users of tclConfig.sh that may build shared or static.
	DLLSUFFIX="\${DBGX}.dll"
	LIBSUFFIX="\${DBGX}.a"
	LIBFLAGSUFFIX="\${DBGX}"
	DLLSUFFIX=".dll"
	LIBSUFFIX=".a"
	LIBFLAGSUFFIX=""
	SHLIB_SUFFIX=.dll

	EXTRA_CFLAGS="${extra_cflags}"

	CFLAGS_DEBUG=-g
	CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
	CFLAGS_WARNING="-Wall -Wextra -Wwrite-strings -Wpointer-arith"
	CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith -finput-charset=UTF-8"
	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} -Wc++-compat -fextended-identifiers"
		;;
	esac

	# Specify the CC output file names based on the target name
	CC_OBJNAME="-o \$@"
	CC_EXENAME="-o \$@"

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







-
-
+
+



-
-
+
+










-
+






-
+
+

-
+



-
+

-
-
-
-
+
+
+
+






-
-
+
+


-
+


-
-
+
+



-
+











-
-
-
+
+
+










-
-
+
+







	#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; }
		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result:    Using 64-bit $MACHINE mode" >&5
printf "%s\n" "   Using 64-bit $MACHINE mode" >&6; }
		;;
	    ia64)
		MACHINE="IA64"
		{ $as_echo "$as_me:${as_lineno-$LINENO}: result:    Using 64-bit $MACHINE mode" >&5
$as_echo "   Using 64-bit $MACHINE mode" >&6; }
		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result:    Using 64-bit $MACHINE mode" >&5
printf "%s\n" "   Using 64-bit $MACHINE mode" >&6; }
		;;
	    *)
		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

		    #ifndef _WIN64
			#error 32-bit
		    #endif

int
main ()
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_win_64bit=yes
else
else $as_nop
  tcl_win_64bit=no

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam 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"
		    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result:    Using 64-bit $MACHINE mode" >&5
printf "%s\n" "   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; }
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: using static flags" >&5
printf "%s\n" "using static flags" >&6; }
	    runtime=-MT
	    LIBRARIES="\${STATIC_LIBRARIES}"
	    EXESUFFIX="s\${DBGX}.exe"
	    EXESUFFIX="s.exe"
	else
	    # dynamic
            { $as_echo "$as_me:${as_lineno-$LINENO}: result: using shared flags" >&5
$as_echo "using shared flags" >&6; }
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: using shared flags" >&5
printf "%s\n" "using shared flags" >&6; }
	    runtime=-MD
	    # Add SHLIB_LD_LIBS to the Make rule, not here.
	    LIBRARIES="\${SHARED_LIBRARIES}"
	    EXESUFFIX="\${DBGX}.exe"
	    EXESUFFIX=".exe"
	    case "x`echo \${VisualStudioVersion}`" in
		x1[4-9]*)
		    lflags="${lflags} -nodefaultlib:libucrt.lib"
		    ;;
		*)
		    ;;
	    esac
	fi
	MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -out:\$@"
	# DLLSUFFIX is separate because it is the building block for
	# users of tclConfig.sh that may build shared or static.
	DLLSUFFIX="\${DBGX}.dll"
	LIBSUFFIX="\${DBGX}.lib"
	LIBFLAGSUFFIX="\${DBGX}"
	DLLSUFFIX=".dll"
	LIBSUFFIX=".lib"
	LIBFLAGSUFFIX=""

	if test "$do64bit" != "no" ; then
	    case "$do64bit" in
		amd64|x64|yes)
		    MACHINE="AMD64" ; # assume AMD64 as default 64-bit build
		    ;;
		ia64)
		    MACHINE="IA64"
		    ;;
	    esac
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result:    Using 64-bit $MACHINE mode" >&5
$as_echo "   Using 64-bit $MACHINE mode" >&6; }
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result:    Using 64-bit $MACHINE mode" >&5
printf "%s\n" "   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"
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
4672
4673
4674
4675
4676
4677
4678

4679
4680
4681
4682
4683






4684
4685
4686
4687
4688
4689
4690
4691
4692


4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755

4756
4757
4758

4759
4760
4761
4762
4763
4764
4765
4766
4767


4768
4769
4770
4771

4772
4773
4774
4775
4776
4777
4778
4779
4780
4781





4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795

4796
4797
4798
4799
4800
4801
4802
4803
4804

4805
4806
4807

4808
4809
4810

4811
4812
4813


4814
4815
4816
4817

4818
4819
4820
4821
4822
4823
4824
4825





4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840

4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851

4852
4853
4854

4855
4856
4857

4858
4859
4860


4861
4862
4863
4864

4865
4866
4867
4868


4869
4870
4871
4872

4873
4874
4875
4876
4877

4878
4879
4880
4881





4882
4883
4884
4885
4886
4887
4888
4889
4890
4891

4892
4893
4894
4895
4896
4897
4898
4899
4900
4901

4902
4903
4904

4905
4906
4907

4908
4909
4910


4911
4912
4913
4914

4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955


4956
4957
4958
4959

4960
4961
4962

4963
4964
4965
4966
4967
4968
4969





4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980

4981
4982
4983
4984
4985
4986
4987

4988
4989
4990

4991
4992
4993

4994
4995
4996


4997
4998
4999
5000

5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116


5117
5118
5119
5120



5121
5122
5123
5124

5125
5126
5127
5128


5129
5130
5131
5132
5133

5134
5135
5136
5137
5138
5139
5140
5141
5142


5143
5144
5145

5146
5147
5148

5149
5150
5151
5152
5153
5154
5155
5156

5157

5158
5159


5160
5161
5162

5163
5164
5165
5166
5167

5168


5169
5170
5171
5172
5173
5174
5175
5176
5177

5178
5179
5180
5181
5182
5183

5184
5185
5186

5187
5188
5189
5190
5191
5192


5193
5194
5195


5196
5197
5198
5199
5200
5201


5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481


5482
5483
5484

5485
5486
5487

5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507

5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524

5525
5526
5527


5528
5529
5530
5531
5532
5533
5534





5535
5536
5537
5538
5539
5540
5541
5542


5543
5544
5545



5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568


5569
5570
5571
5572
5573


5574
5575
5576
5577
5578
5579
5580
5581
5582







-
+




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

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


















-
+
+

-
+








-
-
+
+


-
+









-
-
-
-
-
+
+
+
+
+
+








-
+








-
+
+

-
+


-
+


-
-
+
+


-
+







-
-
-
-
-
+
+
+
+
+
+









-
+










-
+
+

-
+


-
+


-
-
+
+


-
+



-
-
+
+
+

-
+




-




-
-
-
-
-
+
+
+
+
+
+




-
+









-
+
+

-
+


-
+


-
-
+
+


-
+










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





-
-
+
+
+

-
+


-







-
-
-
-
-
+
+
+
+
+
+





-
+






-
+
+

-
+


-
+


-
-
+
+


-
+


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







-
-
+
+
+

-
-
-
+
+
+

-




-
-
+
+
+


-









-
-
+
+

-
+
+

-
+







-

-
+

-
-
+
+

-
+




-

-
-
+
+







-
+





-
+


-
+





-
-
+
+

-
-
+
+




-
-




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

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

-
+
+

-
+



















-
+
+















-
+


-
-
+
+





-
-
-
-
-
+
+
+
+
+



-
-
+
+

-
-
-
+
+
+
+



















-
-
+
+



-
-
+
+







	else
	    LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
	    LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
	fi
    fi

    if test "$do64bit" != "no" ; then
	$as_echo "#define TCL_CFG_DO64BIT 1" >>confdefs.h
	printf "%s\n" "#define TCL_CFG_DO64BIT 1" >>confdefs.h

    fi

    if test "${GCC}" = "yes" ; then
	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SEH support in compiler" >&5
$as_echo_n "checking for SEH support in compiler... " >&6; }
if ${tcl_cv_seh+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if test "$cross_compiling" = yes; then :
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SEH support in compiler" >&5
printf %s "checking for SEH support in compiler... " >&6; }
if test ${tcl_cv_seh+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  if test "$cross_compiling" = yes
then :
  tcl_cv_seh=no
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
else $as_nop

# ac_fn_c_try_run LINENO
# ----------------------
# Try to run 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\""
printf "%s\n" "$ac_try_echo"; } >&5
  (eval "$ac_link") 2>&5
  ac_status=$?
  printf "%s\n" "$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\""
printf "%s\n" "$ac_try_echo"; } >&5
  (eval "$ac_try") 2>&5
  ac_status=$?
  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; }
then :
  ac_retval=0
else $as_nop
  printf "%s\n" "$as_me: program exited with status $ac_status" >&5
       printf "%s\n" "$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
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

	    #define WIN32_LEAN_AND_MEAN
	    #include <windows.h>
	    #undef WIN32_LEAN_AND_MEAN

	    int main(int argc, char** argv) {
		int a, b = 0;
		__try {
		    a = 666 / b;
		}
		__except (EXCEPTION_EXECUTE_HANDLER) {
		    return 0;
		}
		return 1;
	    }

_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
if ac_fn_c_try_run "$LINENO"
then :
  tcl_cv_seh=yes
else
else $as_nop
  tcl_cv_seh=no
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
  conftest.$ac_objext conftest.beam conftest.$ac_ext
fi


fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_seh" >&5
$as_echo "$tcl_cv_seh" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_seh" >&5
printf "%s\n" "$tcl_cv_seh" >&6; }
	if test "$tcl_cv_seh" = "no" ; then

$as_echo "#define HAVE_NO_SEH 1" >>confdefs.h
printf "%s\n" "#define HAVE_NO_SEH 1" >>confdefs.h

	fi

	#
	# Check to see if the excpt.h include file provided contains the
	# definition for EXCEPTION_DISPOSITION; if not, which is the case
	# with Cygwin's version as of 2002-04-10, define it to be int,
	# sufficient for getting the current code to work.
	#
	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for EXCEPTION_DISPOSITION support in include files" >&5
$as_echo_n "checking for EXCEPTION_DISPOSITION support in include files... " >&6; }
if ${tcl_cv_eh_disposition+:} false; then :
  $as_echo_n "(cached) " >&6
else
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for EXCEPTION_DISPOSITION support in include files" >&5
printf %s "checking for EXCEPTION_DISPOSITION support in include files... " >&6; }
if test ${tcl_cv_eh_disposition+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

#	    define WIN32_LEAN_AND_MEAN
#	    include <windows.h>
#	    undef WIN32_LEAN_AND_MEAN

int
main ()
main (void)
{

		EXCEPTION_DISPOSITION x;

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_eh_disposition=yes
else
else $as_nop
  tcl_cv_eh_disposition=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_eh_disposition" >&5
$as_echo "$tcl_cv_eh_disposition" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_eh_disposition" >&5
printf "%s\n" "$tcl_cv_eh_disposition" >&6; }
	if test "$tcl_cv_eh_disposition" = "no" ; then

$as_echo "#define EXCEPTION_DISPOSITION int" >>confdefs.h
printf "%s\n" "#define EXCEPTION_DISPOSITION int" >>confdefs.h

	fi

	# Check to see if winnt.h defines CHAR, SHORT, and LONG
	# even if VOID has already been #defined. The win32api
	# used by mingw and cygwin is known to do this.

	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for winnt.h that ignores VOID define" >&5
$as_echo_n "checking for winnt.h that ignores VOID define... " >&6; }
if ${tcl_cv_winnt_ignore_void+:} false; then :
  $as_echo_n "(cached) " >&6
else
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for winnt.h that ignores VOID define" >&5
printf %s "checking for winnt.h that ignores VOID define... " >&6; }
if test ${tcl_cv_winnt_ignore_void+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

		#define VOID void
		#define WIN32_LEAN_AND_MEAN
		#include <windows.h>
		#undef WIN32_LEAN_AND_MEAN

int
main ()
main (void)
{

		CHAR c;
		SHORT s;
		LONG l;

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_winnt_ignore_void=yes
else
else $as_nop
  tcl_cv_winnt_ignore_void=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam 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; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_winnt_ignore_void" >&5
printf "%s\n" "$tcl_cv_winnt_ignore_void" >&6; }
	if test "$tcl_cv_winnt_ignore_void" = "yes" ; then

$as_echo "#define HAVE_WINNT_IGNORE_VOID 1" >>confdefs.h
printf "%s\n" "#define HAVE_WINNT_IGNORE_VOID 1" >>confdefs.h

	fi

	ac_fn_c_check_header_mongrel "$LINENO" "stdbool.h" "ac_cv_header_stdbool_h" "$ac_includes_default"
if test "x$ac_cv_header_stdbool_h" = xyes; then :
	ac_fn_c_check_header_compile "$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
printf "%s\n" "#define HAVE_STDBOOL_H 1" >>confdefs.h

fi



	# See if the compiler supports casting to a union type.
	# This is used to stop gcc from printing a compiler
	# warning when initializing a union member.

	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cast to union support" >&5
$as_echo_n "checking for cast to union support... " >&6; }
if ${tcl_cv_cast_to_union+:} false; then :
  $as_echo_n "(cached) " >&6
else
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for cast to union support" >&5
printf %s "checking for cast to union support... " >&6; }
if test ${tcl_cv_cast_to_union+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
main (void)
{

		  union foo { int i; double d; };
		  union foo f = (union foo) (int) 0;

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_cast_to_union=yes
else
else $as_nop
  tcl_cv_cast_to_union=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.beam 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; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cast_to_union" >&5
printf "%s\n" "$tcl_cv_cast_to_union" >&6; }
	if test "$tcl_cv_cast_to_union" = "yes"; then

$as_echo "#define HAVE_CAST_TO_UNION 1" >>confdefs.h
printf "%s\n" "#define HAVE_CAST_TO_UNION 1" >>confdefs.h

	fi
    fi

    # DL_LIBS is empty, but then we match the Unix version







ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "
#include <stdint.h>

"
if test "x$ac_cv_type_intptr_t" = xyes
then :

printf "%s\n" "#define HAVE_INTPTR_T 1" >>confdefs.h


fi
ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "
#include <stdint.h>

"
if test "x$ac_cv_type_uintptr_t" = xyes
then :

printf "%s\n" "#define HAVE_UINTPTR_T 1" >>confdefs.h


fi


#--------------------------------------------------------------------
# man2tcl needs this so that it can use errno.h
#--------------------------------------------------------------------

ac_fn_c_check_header_mongrel "$LINENO" "errno.h" "ac_cv_header_errno_h" "$ac_includes_default"
if test "x$ac_cv_header_errno_h" = xyes; then :
ac_fn_c_check_header_compile "$LINENO" "errno.h" "ac_cv_header_errno_h" "$ac_includes_default"
if test "x$ac_cv_header_errno_h" = xyes
then :

else
else $as_nop
  MAN2TCLFLAGS="-DNO_ERRNO_H"
fi




#-------------------------------------------
#     Check for _strtoi64
#-------------------------------------------

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking availability of _strtoi64" >&5
$as_echo_n "checking availability of _strtoi64... " >&6; }
if ${tcl_cv_strtoi64+:} false; then :
  $as_echo_n "(cached) " >&6
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking availability of _strtoi64" >&5
printf %s "checking availability of _strtoi64... " >&6; }
if test ${tcl_cv_strtoi64+y}
then :
  printf %s "(cached) " >&6
else $as_nop

    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <stdlib.h>
int
main ()
main (void)
{
_strtoi64(0,0,0)
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_strtoi64=yes
else
else $as_nop
  tcl_cv_strtoi64=no
fi
rm -f core conftest.err conftest.$ac_objext \
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    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; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_strtoi64" >&5
printf "%s\n" "$tcl_cv_strtoi64" >&6; }
if test $tcl_cv_strtoi64 = no; then

$as_echo "#define NO_STRTOI64 1" >>confdefs.h
printf "%s\n" "#define NO_STRTOI64 1" >>confdefs.h

fi

ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default"
if test "x$ac_cv_type_intptr_t" = xyes
then :


printf "%s\n" "#define HAVE_INTPTR_T 1" >>confdefs.h

else $as_nop

    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pointer-size signed integer type" >&5
printf %s "checking for pointer-size signed integer type... " >&6; }
if test ${tcl_cv_intptr_t+y}
then :
  printf %s "(cached) " >&6
else $as_nop

    for tcl_cv_intptr_t in "int" "long" "__int64" none; do
	if test "$tcl_cv_intptr_t" != none; then
	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$ac_includes_default
int
main (void)
{
static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($tcl_cv_intptr_t))];
test_array [0] = 0;
return test_array [0];

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_ok=yes
else $as_nop
  tcl_ok=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
	    test "$tcl_ok" = yes && break; fi
    done
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_intptr_t" >&5
printf "%s\n" "$tcl_cv_intptr_t" >&6; }
    if test "$tcl_cv_intptr_t" != none; then

printf "%s\n" "#define intptr_t $tcl_cv_intptr_t" >>confdefs.h

    fi

fi

ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default"
if test "x$ac_cv_type_uintptr_t" = xyes
then :


printf "%s\n" "#define HAVE_UINTPTR_T 1" >>confdefs.h

else $as_nop

    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pointer-size unsigned integer type" >&5
printf %s "checking for pointer-size unsigned integer type... " >&6; }
if test ${tcl_cv_uintptr_t+y}
then :
  printf %s "(cached) " >&6
else $as_nop

    for tcl_cv_uintptr_t in "unsigned int" "unsigned long" "unsigned __int64" \
	    none; do
	if test "$tcl_cv_uintptr_t" != none; then
	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$ac_includes_default
int
main (void)
{
static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($tcl_cv_uintptr_t))];
test_array [0] = 0;
return test_array [0];

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_ok=yes
else $as_nop
  tcl_ok=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
	    test "$tcl_ok" = yes && break; fi
    done
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_uintptr_t" >&5
printf "%s\n" "$tcl_cv_uintptr_t" >&6; }
    if test "$tcl_cv_uintptr_t" != none; then

printf "%s\n" "#define uintptr_t $tcl_cv_uintptr_t" >>confdefs.h

    fi

fi


#--------------------------------------------------------------------
# Windows XP theme engine header for Ttk
#--------------------------------------------------------------------

ac_fn_c_check_header_compile "$LINENO" "uxtheme.h" "ac_cv_header_uxtheme_h" "#include <windows.h>
"
if test "x$ac_cv_header_uxtheme_h" = xyes; then :
  $as_echo "#define HAVE_UXTHEME_H 1" >>confdefs.h
if test "x$ac_cv_header_uxtheme_h" = xyes
then :
  printf "%s\n" "#define HAVE_UXTHEME_H 1" >>confdefs.h

else
  { $as_echo "$as_me:${as_lineno-$LINENO}: xpnative theme will be unavailable" >&5
$as_echo "$as_me: xpnative theme will be unavailable" >&6;}
else $as_nop
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: xpnative theme will be unavailable" >&5
printf "%s\n" "$as_me: xpnative theme will be unavailable" >&6;}
fi


ac_fn_c_check_header_compile "$LINENO" "vssym32.h" "ac_cv_header_vssym32_h" "#include <windows.h>
#include <uxtheme.h>
"
if test "x$ac_cv_header_vssym32_h" = xyes; then :
  $as_echo "#define HAVE_VSSYM32_H 1" >>confdefs.h
if test "x$ac_cv_header_vssym32_h" = xyes
then :
  printf "%s\n" "#define HAVE_VSSYM32_H 1" >>confdefs.h

fi



#--------------------------------------------------------------------
# Set the default compiler switches based on the --enable-symbols
# option.  This macro depends on C flags, and should be called
# after SC_CONFIG_CFLAGS macro is called.
#--------------------------------------------------------------------


    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build with symbols" >&5
$as_echo_n "checking for build with symbols... " >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build with symbols" >&5
printf %s "checking for build with symbols... " >&6; }
    # Check whether --enable-symbols was given.
if test "${enable_symbols+set}" = set; then :
if test ${enable_symbols+y}
then :
  enableval=$enable_symbols; tcl_ok=$enableval
else
else $as_nop
  tcl_ok=no
fi

# FIXME: Currently, LDFLAGS_DEFAULT is not used, it should work like CFLAGS_DEFAULT.
    if test "$tcl_ok" = "no"; then
	CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)'
	LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'
	DBGX=""

$as_echo "#define NDEBUG 1" >>confdefs.h
printf "%s\n" "#define NDEBUG 1" >>confdefs.h

	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }

	$as_echo "#define TCL_CFG_OPTIMIZED 1" >>confdefs.h
	printf "%s\n" "#define TCL_CFG_OPTIMIZED 1" >>confdefs.h

    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; }
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes (standard debugging)" >&5
printf "%s\n" "yes (standard debugging)" >&6; }
	fi
    fi



    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then

$as_echo "#define TCL_MEM_DEBUG 1" >>confdefs.h
printf "%s\n" "#define TCL_MEM_DEBUG 1" >>confdefs.h

    fi

    if test "$tcl_ok" = "compile" -o "$tcl_ok" = "all"; then

$as_echo "#define TCL_COMPILE_DEBUG 1" >>confdefs.h
printf "%s\n" "#define TCL_COMPILE_DEBUG 1" >>confdefs.h


$as_echo "#define TCL_COMPILE_STATS 1" >>confdefs.h
printf "%s\n" "#define TCL_COMPILE_STATS 1" >>confdefs.h

    fi

    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
	if test "$tcl_ok" = "all"; then
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled symbols mem compile debugging" >&5
$as_echo "enabled symbols mem compile debugging" >&6; }
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: enabled symbols mem compile debugging" >&5
printf "%s\n" "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; }
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: enabled $tcl_ok debugging" >&5
printf "%s\n" "enabled $tcl_ok debugging" >&6; }
	fi
    fi


TK_DBGX=${DBGX}

#--------------------------------------------------------------------
# Embed the manifest if we can determine how
#--------------------------------------------------------------------

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
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
printf %s "checking how to run the C preprocessor... " >&6; }
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
  CPP=
fi
if test -z "$CPP"; then
  if test ${ac_cv_prog_CPP+y}
then :
  printf %s "(cached) " >&6
else $as_nop
      # Double quotes because $CC needs to be expanded
    for CPP in "$CC -E" "$CC -E -traditional-cpp" 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.
  # On the NeXT, cc -E runs the code through the compiler's parser,
  # not just through cpp. "Syntax error" is here to catch this case.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <limits.h>
		     Syntax error
_ACEOF
if ac_fn_c_try_cpp "$LINENO"
then :

else $as_nop
  # Broken: fails on valid input.
continue
fi
rm -f conftest.err conftest.i conftest.$ac_ext

  # OK, works on sane cases.  Now check whether nonexistent headers
  # can be detected and how.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <ac_nonexistent.h>
_ACEOF
if ac_fn_c_try_cpp "$LINENO"
then :
  # Broken: success on invalid input.
continue
else $as_nop
  # Passes both tests.
ac_preproc_ok=:
break
fi
rm -f conftest.err conftest.i conftest.$ac_ext

done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
rm -f conftest.i conftest.err conftest.$ac_ext
if $ac_preproc_ok
then :
  break
fi

    done
    ac_cv_prog_CPP=$CPP

fi
  CPP=$ac_cv_prog_CPP
else
  ac_cv_prog_CPP=$CPP
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
printf "%s\n" "$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.
  # On the NeXT, cc -E runs the code through the compiler's parser,
  # not just through cpp. "Syntax error" is here to catch this case.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <limits.h>
		     Syntax error
_ACEOF
if ac_fn_c_try_cpp "$LINENO"
then :

else $as_nop
  # Broken: fails on valid input.
continue
fi
rm -f conftest.err conftest.i conftest.$ac_ext

  # OK, works on sane cases.  Now check whether nonexistent headers
  # can be detected and how.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <ac_nonexistent.h>
_ACEOF
if ac_fn_c_try_cpp "$LINENO"
then :
  # Broken: success on invalid input.
continue
else $as_nop
  # Passes both tests.
ac_preproc_ok=:
break
fi
rm -f conftest.err conftest.i conftest.$ac_ext

done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
rm -f conftest.i conftest.err conftest.$ac_ext
if $ac_preproc_ok
then :

else $as_nop
  { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
See \`config.log' for more details" "$LINENO" 5; }
fi

ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu


{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
printf %s "checking for grep that handles long lines and -e... " >&6; }
if test ${ac_cv_path_GREP+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    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
  printf %s 0123456789 >"conftest.in"
  while :
  do
    cat "conftest.in" "conftest.in" >"conftest.tmp"
    mv "conftest.tmp" "conftest.in"
    cp "conftest.in" "conftest.nl"
    printf "%s\n" 'GREP' >> "conftest.nl"
    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
    as_fn_arith $ac_count + 1 && ac_count=$as_val
    if test $ac_count -gt ${ac_path_GREP_max-0}; then
      # Best one so far, save it but keep looking for a better one
      ac_cv_path_GREP="$ac_path_GREP"
      ac_path_GREP_max=$ac_count
    fi
    # 10*(2^10) chars as input seems more than enough
    test $ac_count -gt 10 && break
  done
  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
esac

      $ac_path_GREP_found && break 3
    done
  done
  done
IFS=$as_save_IFS
  if test -z "$ac_cv_path_GREP"; then
    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
  fi
else
  ac_cv_path_GREP=$GREP
fi

fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
printf "%s\n" "$ac_cv_path_GREP" >&6; }
 GREP="$ac_cv_path_GREP"


{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
printf %s "checking for egrep... " >&6; }
if test ${ac_cv_path_EGREP+y}
then :
  printf %s "(cached) " >&6
else $as_nop
  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
  case $as_dir in #(((
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    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
  printf %s 0123456789 >"conftest.in"
  while :
  do
    cat "conftest.in" "conftest.in" >"conftest.tmp"
    mv "conftest.tmp" "conftest.in"
    cp "conftest.in" "conftest.nl"
    printf "%s\n" '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
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
printf "%s\n" "$ac_cv_path_EGREP" >&6; }
 EGREP="$ac_cv_path_EGREP"



    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to embed manifest" >&5
$as_echo_n "checking whether to embed manifest... " >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to embed manifest" >&5
printf %s "checking whether to embed manifest... " >&6; }
    # Check whether --enable-embedded-manifest was given.
if test "${enable_embedded_manifest+set}" = set; then :
if test ${enable_embedded_manifest+y}
then :
  enableval=$enable_embedded_manifest; embed_ok=$enableval
else
else $as_nop
  embed_ok=yes
fi


    VC_MANIFEST_EMBED_DLL=
    VC_MANIFEST_EMBED_EXE=
    result=no
    if test "$embed_ok" = "yes" -a "${SHARED_BUILD}" = "1" \
       -a "$GCC" != "yes" ; then
	# Add the magic to embed the manifest into the dll/exe
	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

#if defined(_MSC_VER) && _MSC_VER >= 1400
print("manifest needed")
#endif

_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  $EGREP "manifest needed" >/dev/null 2>&1; then :
  $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 \[email protected] ; then mt.exe -nologo -manifest \[email protected] wish.exe.manifest -outputresource:\$@\;2 ; fi"
	VC_MANIFEST_EMBED_EXE="if test -f \[email protected] ; then mt.exe -nologo -manifest \[email protected] 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*
rm -rf conftest*

    fi
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $result" >&5
$as_echo "$result" >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $result" >&5
printf "%s\n" "$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}${TCL_DBGX}${EXEEXT}
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_TCLSH" >&5
$as_echo "$BUILD_TCLSH" >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tclsh in Tcl build directory" >&5
printf %s "checking for tclsh in Tcl build directory... " >&6; }
    BUILD_TCLSH=${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${EXEEXT}
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $BUILD_TCLSH" >&5
printf "%s\n" "$BUILD_TCLSH" >&6; }



    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tclsh" >&5
$as_echo_n "checking for tclsh... " >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tclsh" >&5
printf %s "checking for tclsh... " >&6; }

    if ${ac_cv_path_tclsh+:} false; then :
  $as_echo_n "(cached) " >&6
else
    if test ${ac_cv_path_tclsh+y}
then :
  printf %s "(cached) " >&6
else $as_nop

	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; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $TCLSH_PROG" >&5
printf "%s\n" "$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; }
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: No tclsh found on PATH" >&5
printf "%s\n" "No tclsh found on PATH" >&6; }
    fi



#------------------------------------------------------------------------
# tkConfig.sh refers to this by a different name
#------------------------------------------------------------------------
4913
4914
4915
4916
4917
4918
4919

4920




4921
4922
4923
4924
4925
4926
4927
5590
5591
5592
5593
5594
5595
5596
5597

5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608







+
-
+
+
+
+







TK_SHARED_LIB_SUFFIX="\${NODOT_VERSION}${DLLSUFFIX}"
TK_UNSHARED_LIB_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"
TK_EXPORT_FILE_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"

eval "TK_SRC_DIR=\"`cd $srcdir/..; pwd`\""

eval "TK_DLL_FILE=tk$VER${DLLSUFFIX}"
if test ${SHARED_BUILD} = 0 -o "$GCC" != "yes" ; then
eval "TK_LIB_FILE=${LIBPREFIX}tk$VER${LIBSUFFIX}"
 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}"
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
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







-
-
-
-
+
-


-
-
-
-
+
-














-
-








#--------------------------------------------------------------------
# Adjust the defines for how the resources are built depending
# on symbols and static vs. shared.
#--------------------------------------------------------------------

if test ${SHARED_BUILD} = 0 -o "$TCL_NEEDS_EXP_FILE" = 0; then
    if test "${DBGX}" = "d"; then
        RC_DEFINES="${RC_DEFINE} STATIC_BUILD ${RC_DEFINE} DEBUG"
    else
        RC_DEFINES="${RC_DEFINE} STATIC_BUILD"
    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









5083
5084
5085
5086
5087
5088
5089
5090
5091


5092
5093
5094
5095
5096
5097
5098
5754
5755
5756
5757
5758
5759
5760


5761
5762
5763
5764
5765
5766
5767
5768
5769







-
-
+
+







# 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;} ;;
      *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
printf "%s\n" "$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
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
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







-
+






-
-
+
+













-
-
+
+







    esac |
    sort
) |
  sed '
     /^ac_cv_env_/b end
     t clear
     :clear
     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
     s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/
     t end
     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
     :end' >>confcache
if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
  if test -w "$cache_file"; then
    if test "x$cache_file" != "x/dev/null"; then
      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
$as_echo "$as_me: updating cache $cache_file" >&6;}
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
printf "%s\n" "$as_me: updating cache $cache_file" >&6;}
      if test ! -f "$cache_file" || test -h "$cache_file"; then
	cat confcache >"$cache_file"
      else
        case $cache_file in #(
        */* | ?:*)
	  mv -f confcache "$cache_file"$$ &&
	  mv -f "$cache_file"$$ "$cache_file" ;; #(
        *)
	  mv -f confcache "$cache_file" ;;
	esac
      fi
    fi
  else
    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;}
  fi
fi
rm -f confcache

test "x$prefix" = xNONE && prefix=$ac_default_prefix
# Let make expand exec_prefix.
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
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
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







-
+















-
-
+
+








ac_libobjs=
ac_ltlibobjs=
U=
for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
  # 1. Remove the extension, and $U if already installed.
  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
  ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"`
  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
  #    will be set to the directory where LIBOBJS objects are built.
  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
done
LIBOBJS=$ac_libobjs

LTLIBOBJS=$ac_ltlibobjs



: "${CONFIG_STATUS=./config.status}"
ac_write_fail=0
ac_clean_files_save=$ac_clean_files
ac_clean_files="$ac_clean_files $CONFIG_STATUS"
{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;}
as_write_fail=0
cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
#! $SHELL
# Generated by $as_me.
# Run this file to recreate the current configuration.
# Compiler output produced by configure, useful for debugging
# configure, is in config.log if it exists.
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
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







+
-
+
+






-
+









+
+
+
+
+
+
+
+



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


-
+








-
-
-
-
-
-
-








+
-
-
+
+
+
+
+











-
+



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












-
+

-
+


+







cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##

# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
as_nop=:
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
if test ${ZSH_VERSION+y} && (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
else $as_nop
  case `(set -o) 2>/dev/null` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;
esac
fi



# Reset variables that may have inherited troublesome values from
# the environment.

# IFS needs to be set, to space, tab, and newline, in precisely that order.
# (If _AS_PATH_WALK were called with IFS unset, it would have the
# side effect of setting IFS to empty, thus disabling word splitting.)
# Quoting is to prevent editors from complaining about space-tab.
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 --'
IFS=" ""	$as_nl"

elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
  as_echo='printf %s\n'
  as_echo_n='printf %s'
PS1='$ '
PS2='> '
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
PS4='+ '
      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

# Ensure predictable behavior from utilities with locale-dependent output.
LC_ALL=C
export LC_ALL
    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
LANGUAGE=C
export LANGUAGE

# We cannot yet rely on "unset" to work, but we need these variables
# to be unset--not just set to an empty or harmless value--now, to
# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh).  This construct
# also avoids known problems related to "unset" and subshell syntax
# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
do eval test \${$as_var+y} \
  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
done

# Ensure that fds 0, 1, and 2 are open.
if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
if (exec 3>&2)            ; then :; else exec 2>/dev/null; fi

# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
if ${PATH_SEPARATOR+false} :; then
  PATH_SEPARATOR=:
  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
      PATH_SEPARATOR=';'
  }
fi


# IFS
# We need space, tab and new line, in precisely that order.  Quoting is
# there to prevent editors from complaining about space-tab.
# (If _AS_PATH_WALK were called with IFS unset, it would disable word
# splitting by setting IFS to empty value.)
IFS=" ""	$as_nl"

# Find who we are.  Look in the path if we contain no directory separator.
as_myself=
case $0 in #((
  *[\\/]* ) as_myself=$0 ;;
  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  case $as_dir in #(((
  test -z "$as_dir" && as_dir=.
    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
    '') as_dir=./ ;;
    */) ;;
    *) as_dir=$as_dir/ ;;
  esac
    test -r "$as_dir$0" && as_myself=$as_dir$0 && break
  done
IFS=$as_save_IFS

     ;;
esac
# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
  as_myself=$0
fi
if test ! -f "$as_myself"; then
  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
  exit 1
fi

# Unset variables that we do not need and which cause bugs (e.g. in
# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
# suppresses any "Segmentation fault" message there.  '((' could
# trigger a bug in pdksh 5.2.14.
for as_var in BASH_ENV ENV MAIL MAILPATH
do eval test x\${$as_var+set} = xset \
  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
done
PS1='$ '
PS2='> '
PS4='+ '

# NLS nuisances.
LC_ALL=C
export LC_ALL
LANGUAGE=C
export LANGUAGE

# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH


# as_fn_error STATUS ERROR [LINENO LOG_FD]
# ----------------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
# script with STATUS, using 1 if that was 0.
as_fn_error ()
{
  as_status=$1; test $as_status -eq 0 && as_status=1
  if test "$4"; then
    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
  fi
  $as_echo "$as_me: error: $2" >&2
  printf "%s\n" "$as_me: error: $2" >&2
  as_fn_exit $as_status
} # as_fn_error



# as_fn_set_status STATUS
# -----------------------
# Set $? to STATUS, without forking.
as_fn_set_status ()
{
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
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







+






-
+
+




-
+











-
+
+




-
+







# ---------------
# 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 :
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
else $as_nop
  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 :
if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
then :
  eval 'as_fn_arith ()
  {
    as_val=$(( $* ))
  }'
else
else $as_nop
  as_fn_arith ()
  {
    as_val=`expr "$@" || test $? -eq 1`
  }
fi # as_fn_arith


5451
5452
5453
5454
5455
5456
5457
5458

5459
5460
5461
5462
5463
5464
5465
6105
6106
6107
6108
6109
6110
6111

6112
6113
6114
6115
6116
6117
6118
6119







-
+







  as_dirname=false
fi

as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
	 X"$0" : 'X\(//\)$' \| \
	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X/"$0" |
printf "%s\n" X/"$0" |
    sed '/^.*\/\([^/][^/]*\)\/*$/{
	    s//\1/
	    q
	  }
	  /^X\/\(\/\/\)$/{
	    s//\1/
	    q
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
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







+
+
+
+












+
+
+
+
+
+







# 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


# Determine whether it's possible to make 'echo' print without a newline.
# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
# for compatibility with existing Makefiles.
ECHO_C= ECHO_N= ECHO_T=
case `echo -n x` in #(((((
-n*)
  case `echo 'xy\c'` in
  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
  xy)  ECHO_C='\c';;
  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
       ECHO_T='	';;
  esac;;
*)
  ECHO_N='-n';;
esac

# For backward compatibility with old third-party macros, we provide
# the shell variables $as_echo and $as_echo_n.  New code should use
# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
as_echo='printf %s\n'
as_echo_n='printf %s'

rm -f conf$$ conf$$.exe conf$$.file
if test -d conf$$.dir; then
  rm -f conf$$.dir/conf$$.file
else
  rm -f conf$$.dir
  mkdir conf$$.dir 2>/dev/null
5527
5528
5529
5530
5531
5532
5533
5534

5535
5536
5537
5538
5539
5540
5541
5542
5543

5544
5545
5546
5547
5548
5549
5550
6191
6192
6193
6194
6195
6196
6197

6198
6199
6200
6201
6202
6203
6204
6205
6206

6207
6208
6209
6210
6211
6212
6213
6214







-
+








-
+







  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=`printf "%s\n" "$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" |
printf "%s\n" X"$as_dir" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q
5598
5599
5600
5601
5602
5603
5604
5605
5606


5607
5608
5609
5610
5611
5612
5613
6262
6263
6264
6265
6266
6267
6268


6269
6270
6271
6272
6273
6274
6275
6276
6277







-
-
+
+







test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# Save the log message, to keep $0 and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by $as_me, which was
generated by GNU Autoconf 2.69.  Invocation command line was
This file was extended by tk $as_me 8.7, which was
generated by GNU Autoconf 2.70.  Invocation command line was

  CONFIG_FILES    = $CONFIG_FILES
  CONFIG_HEADERS  = $CONFIG_HEADERS
  CONFIG_LINKS    = $CONFIG_LINKS
  CONFIG_COMMANDS = $CONFIG_COMMANDS
  $ $0 $@

5648
5649
5650
5651
5652
5653
5654


5655
5656

5657
5658
5659


5660
5661
5662

5663
5664
5665
5666
5667
5668
5669
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321

6322
6323


6324
6325
6326
6327

6328
6329
6330
6331
6332
6333
6334
6335







+
+

-
+

-
-
+
+


-
+








Configuration files:
$config_files

Report bugs to the package provider."

_ACEOF
ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"`
ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"`
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
config.status
configured by $0, generated by GNU Autoconf 2.69,
tk config.status 8.7
configured by $0, generated by GNU Autoconf 2.70,
  with options \\"\$ac_cs_config\\"

Copyright (C) 2012 Free Software Foundation, Inc.
Copyright (C) 2020 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."

ac_pwd='$ac_pwd'
srcdir='$srcdir'
test -n "\$AWK" || AWK=awk
_ACEOF
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
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







-
+

-
+





-
+





-
+







  esac

  case $ac_option in
  # Handling of the options.
  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
    ac_cs_recheck=: ;;
  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
    $as_echo "$ac_cs_version"; exit ;;
    printf "%s\n" "$ac_cs_version"; exit ;;
  --config | --confi | --conf | --con | --co | --c )
    $as_echo "$ac_cs_config"; exit ;;
    printf "%s\n" "$ac_cs_config"; exit ;;
  --debug | --debu | --deb | --de | --d | -d )
    debug=: ;;
  --file | --fil | --fi | --f )
    $ac_shift
    case $ac_optarg in
    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
    *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
    '') as_fn_error $? "missing file argument" ;;
    esac
    as_fn_append CONFIG_FILES " '$ac_optarg'"
    ac_need_defaults=false;;
  --he | --h |  --help | --hel | -h )
    $as_echo "$ac_cs_usage"; exit ;;
    printf "%s\n" "$ac_cs_usage"; exit ;;
  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
  | -silent | --silent | --silen | --sile | --sil | --si | --s)
    ac_cs_silent=: ;;

  # This is an error.
  -*) as_fn_error $? "unrecognized option: \`$1'
Try \`$0 --help' for more information." ;;
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
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







-
+













-
+







fi

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then
  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
  shift
  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
  \printf "%s\n" "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"
  printf "%s\n" "$ac_log"
} >&5

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
_ACEOF

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
5775
5776
5777
5778
5779
5780
5781
5782

5783
5784
5785
5786
5787
5788
5789
6441
6442
6443
6444
6445
6446
6447

6448
6449
6450
6451
6452
6453
6454
6455







-
+









# 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
  test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files
fi

# Have a temporary directory for convenience.  Make it in the build tree
# simply because there is no reason against having it here, and in addition,
# creating and moving files from /tmp can sometimes cause problems.
# Hook for its removal unless debugging.
# Note that there is a small window in which the directory will not be cleaned:
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
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







-
+







-
+



-
-
+
+




-
+
















-
+







	 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
      case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
      as_fn_append ac_file_inputs " '$ac_f'"
    done

    # Let's still pretend it is `configure' which instantiates (i.e., don't
    # use $as_me), people would be surprised to read:
    #    /* config.h.  Generated by config.status.  */
    configure_input='Generated from '`
	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
	  printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
	`' by configure.'
    if test x"$ac_file" != x-; then
      configure_input="$ac_file.  $configure_input"
      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
$as_echo "$as_me: creating $ac_file" >&6;}
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
printf "%s\n" "$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" |
       ac_sed_conf_input=`printf "%s\n" "$configure_input" |
       sed 's/[\\\\&|]/\\\\&/g'`;; #(
    *) ac_sed_conf_input=$configure_input;;
    esac

    case $ac_tag in
    *:-:* | *:-) cat >"$ac_tmp/stdin" \
      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
    esac
    ;;
  esac

  ac_dir=`$as_dirname -- "$ac_file" ||
$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	 X"$ac_file" : 'X\(//\)[^/]' \| \
	 X"$ac_file" : 'X\(//\)$' \| \
	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$ac_file" |
printf "%s\n" X"$ac_file" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q
6062
6063
6064
6065
6066
6067
6068
6069

6070
6071

6072
6073
6074
6075
6076
6077
6078
6728
6729
6730
6731
6732
6733
6734

6735
6736

6737
6738
6739
6740
6741
6742
6743
6744







-
+

-
+







	  s/.*/./; q'`
  as_dir="$ac_dir"; as_fn_mkdir_p
  ac_builddir=.

case "$ac_dir" in
.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
*)
  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
  ac_dir_suffix=/`printf "%s\n" "$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_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
  case $ac_top_builddir_sub in
  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
  esac ;;
esac
ac_abs_top_builddir=$ac_pwd
ac_abs_builddir=$ac_pwd$ac_dir_suffix
6117
6118
6119
6120
6121
6122
6123
6124
6125


6126
6127
6128
6129
6130
6131
6132
6783
6784
6785
6786
6787
6788
6789


6790
6791
6792
6793
6794
6795
6796
6797
6798







-
-
+
+







/@docdir@/p
/@infodir@/p
/@localedir@/p
/@mandir@/p'
case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
*datarootdir*) ac_datarootdir_seen=yes;;
*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
  ac_datarootdir_hack='
  s&@datadir@&$datadir&g
  s&@docdir@&$docdir&g
  s&@infodir@&$infodir&g
  s&@localedir@&$localedir&g
6160
6161
6162
6163
6164
6165
6166
6167

6168
6169

6170
6171
6172
6173
6174
6175
6176
6826
6827
6828
6829
6830
6831
6832

6833
6834

6835
6836
6837
6838
6839
6840
6841
6842







-
+

-
+







eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5

test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
      "$ac_tmp/out"`; test -z "$ac_out"; } &&
  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
  { printf "%s\n" "$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'
printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined.  Please make sure it is defined" >&2;}

  rm -f "$ac_tmp/stdin"
  case $ac_file in
  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
  esac \
6209
6210
6211
6212
6213
6214
6215
6216
6217


6218
6219
6220

6875
6876
6877
6878
6879
6880
6881


6882
6883
6884
6885
6886
6887







-
-
+
+



+
  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
  exec 5>>config.log
  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
  # would make configure fail if this is the last instruction.
  $ac_cs_success || as_fn_exit 1
fi
if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
fi



Changes to win/configure.ac.

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





+
-
-
+
+







#! /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.7])
AC_INIT(../generic/tk.h)
AC_PREREQ(2.69)
AC_CONFIG_SRCDIR([../generic/tk.h])
AC_PREREQ([2.70])

# 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
38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53







-
+







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

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.
91
92
93
94
95
96
97




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

112
113
114
115
116
































117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

116


117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171


172
173
174
175
176
177
178







+
+
+
+













-
+
-
-



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




















-
-







#--------------------------------------------------------------------
# The statements below define a collection of compile flags.  This
# macro depends on the value of SHARED_BUILD, and should be called
# after SC_ENABLE_SHARED checks the configure switches.
#--------------------------------------------------------------------

SC_CONFIG_CFLAGS

AC_CHECK_TYPES([intptr_t, uintptr_t],,,[[
#include <stdint.h>
]])

#--------------------------------------------------------------------
# man2tcl needs this so that it can use errno.h
#--------------------------------------------------------------------

AC_CHECK_HEADER(errno.h, , MAN2TCLFLAGS="-DNO_ERRNO_H")
AC_SUBST(MAN2TCLFLAGS)

#-------------------------------------------
#     Check for _strtoi64
#-------------------------------------------

AC_CACHE_CHECK([availability of _strtoi64], tcl_cv_strtoi64, [
    AC_TRY_LINK([#include <stdlib.h>],
    AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <stdlib.h>]], [[_strtoi64(0,0,0)]])],[tcl_cv_strtoi64=yes],[tcl_cv_strtoi64=no])])
	    [_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
158
159
160
161
162
163
164

165




166
167
168
169
170
171
172
191
192
193
194
195
196
197
198

199
200
201
202
203
204
205
206
207
208
209







+
-
+
+
+
+







TK_SHARED_LIB_SUFFIX="\${NODOT_VERSION}${DLLSUFFIX}"
TK_UNSHARED_LIB_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"
TK_EXPORT_FILE_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"

eval "TK_SRC_DIR=\"`cd $srcdir/..; pwd`\""

eval "TK_DLL_FILE=tk$VER${DLLSUFFIX}"
if test ${SHARED_BUILD} = 0 -o "$GCC" != "yes" ; then
eval "TK_LIB_FILE=${LIBPREFIX}tk$VER${LIBSUFFIX}"
 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}"
190
191
192
193
194
195
196
197
198
199
200

201
202
203
204
205
206
207

208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
227
228
229
230
231
232
233




234

235
236




237

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

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

273
274
275
276
277
278
279







-
-
-
-
+
-


-
-
-
-
+
-




















-















-








#--------------------------------------------------------------------
# Adjust the defines for how the resources are built depending
# on symbols and static vs. shared.
#--------------------------------------------------------------------

if test ${SHARED_BUILD} = 0 -o "$TCL_NEEDS_EXP_FILE" = 0; then
    if test "${DBGX}" = "d"; then
        RC_DEFINES="${RC_DEFINE} STATIC_BUILD ${RC_DEFINE} DEBUG"
    else
        RC_DEFINES="${RC_DEFINE} STATIC_BUILD"
    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.`"
AC_SUBST(TK_WIN_VERSION)
# X86|AMD64|IA64 for manifest
AC_SUBST(MACHINE)

AC_SUBST(TK_VERSION)
AC_SUBST(TK_MAJOR_VERSION)
AC_SUBST(TK_MINOR_VERSION)
AC_SUBST(TK_PATCH_LEVEL)
AC_SUBST(TK_DBGX)
AC_SUBST(TK_LIB_FILE)
AC_SUBST(TK_DLL_FILE)
AC_SUBST(TK_STUB_LIB_FILE)
AC_SUBST(TK_STUB_LIB_FLAG)
AC_SUBST(TK_BUILD_STUB_LIB_SPEC)
AC_SUBST(TK_SRC_DIR)
AC_SUBST(TK_BIN_DIR)

AC_SUBST(TCL_VERSION)
AC_SUBST(TCL_MAJOR_VERSION)
AC_SUBST(TCL_MINOR_VERSION)
AC_SUBST(TCL_PATCH_LEVEL)

AC_SUBST(TCL_SRC_DIR)
AC_SUBST(TCL_BIN_DIR)
AC_SUBST(TCL_DBGX)
AC_SUBST(CFG_TK_SHARED_LIB_SUFFIX)
AC_SUBST(CFG_TK_UNSHARED_LIB_SUFFIX)
AC_SUBST(CFG_TK_EXPORT_FILE_SUFFIX)

AC_SUBST(CFLAGS_DEFAULT)
AC_SUBST(EXTRA_CFLAGS)
AC_SUBST(CYGPATH)
299
300
301
302
303
304
305
306


307
308
309

310
326
327
328
329
330
331
332

333
334
335
336

337
338







-
+
+


-
+

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)
AC_CONFIG_FILES([Makefile tkConfig.sh wish.exe.manifest])
AC_OUTPUT

dnl Local Variables:
dnl mode: autoconf;
dnl mode: autoconf
dnl End:

Changes to win/makefile.vc.

16
17
18
19
20
21
22



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







+
+
+








# General usage:
#   nmake [-nologo] -f makefile.vc [TARGET|MACRODEF [TARGET|MACRODEF] [...]]
#
# For MACRODEF, see TIP 477 (https://core.tcl-lang.org/tips/doc/trunk/tip/477.md)
# or examine Sections 6-8 in rules.vc. This makefile has the following
# values for the OPTS macro in addition to the ones described there.
#       noembed  = Embeds Tcl scripts into the wish executable. Currently only
#                  applicable for static builds. Non-static builds currently
#                  never embed.
#	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.
54
55
56
57
58
59
60
61

62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
57
58
59
60
61
62
63

64
65
66
67
68
69
70
71

72
73
74
75
76
77
78
79







-
+







-
+







#
# NOTE: For older (Visual C++ 6 or the 2003 SDK), to use the Platform
# SDK (not expressly needed), run setenv.bat after vcvars32.bat
# according to the instructions for it.  This can also turn on the
# 64-bit compiler, if your SDK has it.
#
# Examples:
# Assumign Tcl sources lie in ../../tcl
# Assuming Tcl sources lie in ../../tcl
#       c:\tcl_src\win\>nmake -f makefile.vc release
# If Tcl sources are not in ../../tcl, use the TCLDIR macro to specify dir
#       c:\tcl_src\win\>nmake -f makefile.vc release TCLDIR=c:\src\tcl
# Run the test suite
#       c:\tcl_src\win\>nmake -f makefile.vc test
# Install Tk in location specified by INSTALLDIR macro
#       c:\tcl_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl
# Build release with PDF files
# Build release with PDB files
#       c:\tcl_src\win\>nmake -f makefile.vc release OPTS=pdbs
# Build debug version
#       c:\tcl_src\win\>nmake -f makefile.vc release OPTS=symbols
#
###############################################################################

# The PROJECT macro is used by rules.vc for generating appropriate
98
99
100
101
102
103
104

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







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

135
136
137
138
139
140
141
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144

145
146
147
148
149
150
151
152







+












+
+
+
+
+
+
+

















-
+







!message ***    Tcl sources.
!endif

# Extra makefile options processing for non-standard OPTS values ...
!if "$(OPTS)" == "" || [nmakehlp -f "$(OPTS)" "none"]
HAVE_UXTHEME_H    = 1
TTK_SQUARE_WIDGET = 0
TK_EMBED_SCRIPTS  = $(STATIC_BUILD)
!else
!if [nmakehlp -f $(OPTS) "noxp"]
!message *** Exclude support for XP theme
HAVE_UXTHEME_H  = 0
!else
HAVE_UXTHEME_H  = 1
!endif
!if [nmakehlp -f "$(OPTS)" "square"]
!message *** Include ttk square demo widget
TTK_SQUARE_WIDGET   = 1
!else
TTK_SQUARE_WIDGET   = 0
!endif
!if [nmakehlp -f $(OPTS) "noembed"]
!message *** Option noembed specified. Tk script library will not be appended to the binary.
TK_EMBED_SCRIPTS = 0
!else
!message *** Tk script library will be appended to the binary.
TK_EMBED_SCRIPTS = $(STATIC_BUILD)
!endif
!endif

TK_NO_DEPRECATED = 0
!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]
!if [nmakehlp -f $(CHECKS) "nodep"]
TK_NO_DEPRECATED = 1
!endif
!endif

WISHC 		= "$(OUT_DIR)\$(WISHNAMEPREFIX)c$(VERSION)$(SUFX).exe"

TKTEST		= "$(OUT_DIR)\$(PROJECT)test.exe"
CAT32		= "$(OUT_DIR)\cat32.exe"

WISHOBJS = \
	$(TMP_DIR)\winMain.obj \
!if $(TCL_USE_STATIC_PACKAGES)
!if $(STATIC_BUILD) && !$(STATIC_BUILD)
	$(TCLDDELIB) \
	$(TCLREGLIB) \
!endif
	$(TMP_DIR)\wish.res

TKTESTOBJS = \
	$(TMP_DIR)\testMain.obj \
163
164
165
166
167
168
169

170
171
172
173
174
175
176
177
178
179

180
181
182
183
184
185
186
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199







+










+







	$(TMP_DIR)\tkWinColor.obj \
	$(TMP_DIR)\tkWinConfig.obj \
	$(TMP_DIR)\tkWinCursor.obj \
	$(TMP_DIR)\tkWinDialog.obj \
	$(TMP_DIR)\tkWinDraw.obj \
	$(TMP_DIR)\tkWinEmbed.obj \
	$(TMP_DIR)\tkWinFont.obj \
	$(TMP_DIR)\tkWinIco.obj \
	$(TMP_DIR)\tkWinImage.obj \
	$(TMP_DIR)\tkWinInit.obj \
	$(TMP_DIR)\tkWinKey.obj \
	$(TMP_DIR)\tkWinMenu.obj \
	$(TMP_DIR)\tkWinPixmap.obj \
	$(TMP_DIR)\tkWinPointer.obj \
	$(TMP_DIR)\tkWinRegion.obj \
	$(TMP_DIR)\tkWinScrlbr.obj \
	$(TMP_DIR)\tkWinSend.obj \
	$(TMP_DIR)\tkWinSendCom.obj \
	$(TMP_DIR)\tkWinSysTray.obj \
	$(TMP_DIR)\tkWinWindow.obj \
	$(TMP_DIR)\tkWinWm.obj \
	$(TMP_DIR)\tkWinX.obj \
	$(TMP_DIR)\stubs.obj \
	$(TMP_DIR)\tk3d.obj \
	$(TMP_DIR)\tkArgv.obj \
	$(TMP_DIR)\tkAtom.obj \
305
306
307
308
309
310
311






312
313
314
315
316
317

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

336
337
338

339
340
341
342
343
344
345







+
+
+
+
+
+





-
+


-







	$(TMP_DIR)\ttkStubLib.obj

### The following paths CANNOT have spaces in them as they appear on
### the left side of implicit rules.
XLIBDIR		= $(ROOT)\xlib
TTKDIR		= $(ROOT)\generic\ttk
BITMAPDIR	= $(ROOT)\bitmaps

# Directories where to build TIP430 ZIP files
# One for Tk - always built, contains Tk scripts
# One for Wish - for static builds, contains Tcl+Tk scripts
LIBTKVFS = $(OUT_DIR)\libtk.vfs
WISHSCRIPTZIP = $(OUT_DIR)\wish.zip

# 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 \
CONFIG_DEFS     =/DHAVE_SYS_TYPES_H=1 /DHAVE_SYS_STAT_H=1 \
		 /DHAVE_STRING_H=1 /DHAVE_MEMORY_H=1 \
		 /DHAVE_STRINGS_H=1 \
		 /DSUPPORT_CONFIG_EMBEDDED \
!if $(HAVE_UXTHEME_H)
		 /DHAVE_UXTHEME_H=1 \
!endif
!if $(TTK_SQUARE_WIDGET)
		 /DTTK_SQUARE_WIDGET=1 \
!endif
!if $(TK_NO_DEPRECATED)
342
343
344
345
346
347
348
349

350
351
352

















353
354
355
356
357
358
359
360
361
362
363
364
365
366

367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394







-
+



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







TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
!endif

#---------------------------------------------------------------------
# Project specific targets
#---------------------------------------------------------------------

release:  setup $(TKSTUBLIB) $(WISH)
release:  setup $(TKSTUBLIB) $(WISH) libtkzip embed
all:	  release $(CAT32)
core:	  setup $(TKSTUBLIB) $(TKLIB)
cwish:	  $(WISHC)
libtkzip: setup $(TKSCRIPTZIP)
!if $(TK_EMBED_SCRIPTS)
!if $(STATIC_BUILD)
embed:    setup $(WISH) $(WISHSCRIPTZIP)
	@copy /y /b "$(WISH)"+"$(WISHSCRIPTZIP)" "$(WISH)"
!else
# Note this is currently dead code as TK_EMBED_SCRIPTS is always 0
# for non-static builds as the C code does not currently setup up
# a VFS for a non-static wish.
embed:    setup $(TKLIB) $(TKSCRIPTZIP)
	@copy /y /b "$(TKLIB)"+"$(TKSCRIPTZIP)" "$(TKLIB)"
!endif
!else
# ! TK_EMBED_SCRIPTS - still need to build the zip even if not embedded
embed: $(TKSCRIPTZIP)
!endif

install:  install-binaries install-libraries install-docs
!if $(SYMBOLS)
install:    install-pdbs
!endif
tktest:	  setup $(TKTEST) $(CAT32)

setup: default-setup
462
463
464
465
466
467
468






















469
470
471
472
473
474
475
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532







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







	$(_VC_MANIFEST_EMBED_EXE)


$(TKTEST): $(TKTESTOBJS) $(TKSTUBLIB) $(TKIMPLIB)
	$(GUIEXECMD) -stack:2300000 $**
	$(_VC_MANIFEST_EMBED_EXE)

TKSCRIPTZIPTOP = tk_library
#TKSCRIPTZIPTOP = "tk$(DOTVERSION)"
$(TKSCRIPTZIP): .PHONY
	@echo Building Tk library zip file
	@if not exist "$(LIBTKVFS)" $(MKDIR) "$(LIBTKVFS)"
	@if exist "$(LIBTKVFS)\$(TKSCRIPTZIPTOP)" $(RMDIR) "$(LIBTKVFS)\$(TKSCRIPTZIPTOP)"
	@$(CPYDIR) $(LIBDIR) "$(LIBTKVFS)\$(TKSCRIPTZIPTOP)"
	@echo file delete -force {$@} > "$(OUT_DIR)\zipper.tcl"
	@echo zipfs mkzip {$@} {$(LIBTKVFS)} {$(LIBTKVFS)} >> "$(OUT_DIR)\zipper.tcl"
	@cd "$(OUT_DIR)" && $(TCLSH) zipper.tcl

!if $(STATIC_BUILD)
$(WISHSCRIPTZIP): $(TKSCRIPTZIP)
	@echo Building Wish Tcl+Tk library zip file
	@if exist "$(LIBTKVFS)\tcl_library" $(RMDIR) "$(LIBTKVFS)\tcl_library"
	@echo file delete -force {$@} > "$(OUT_DIR)\zipper.tcl"
	@echo zipfs mount mnt "$(TCLSCRIPTZIP:\=/)" >> "$(OUT_DIR)\zipper.tcl"
	@echo file copy [file join [zipfs root] mnt tcl_library] "$(LIBTKVFS:\=/)" >> "$(OUT_DIR)\zipper.tcl"
	@echo zipfs mkzip {$@} {$(LIBTKVFS)} {$(LIBTKVFS)} >> "$(OUT_DIR)\zipper.tcl"
	@cd "$(OUT_DIR)" && $(TCLSH) zipper.tcl
!endif


$(CAT32): $(_TCLDIR)\win\cat.c
	$(cc32) $(cflags) $(crt) /D_CRT_NONSTDC_NO_DEPRECATE /DCONSOLE /DUNICODE /D_UNICODE -Fo$(TMP_DIR)\ $?
	$(CONEXECMD) /DCONSOLE -stack:16384 $(TMP_DIR)\cat.obj
	$(_VC_MANIFEST_EMBED_EXE)

#---------------------------------------------------------------------
539
540
541
542
543
544
545

546
547
548

549
550
551
552
553
554
555
556
557
558
559
560
561
562

563
564
565

566
567
568
569
570
571
572
596
597
598
599
600
601
602
603
604
605

606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623

624
625
626
627
628
629
630
631







+


-
+














+


-
+







	@$(CPY) "$(OUT_DIR)\*.pdb" "$(BIN_INSTALL_DIR)\"
# "emacs font-lock highlighting fix

#---------------------------------------------------------------------
# Special case object file targets
#---------------------------------------------------------------------

# Note: Static builds now always mandate statically linking Tcl registry etc.
$(TMP_DIR)\testMain.obj: $(WIN_DIR)\winMain.c
	$(cc32) $(appcflags_nostubs) /DTK_TEST /DUNICODE /D_UNICODE \
	    /DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \
	    /DTCL_USE_STATIC_PACKAGES=$(STATIC_BUILD) \
	    -Fo$@ $?

$(TMP_DIR)\tkTest.obj: $(GENERICDIR)\tkTest.c
	$(cc32) $(appcflags_nostubs) -Fo$@ $?

$(TMP_DIR)\tkOldTest.obj: $(GENERICDIR)\tkOldTest.c
	$(cc32) $(appcflags_nostubs) -Fo$@ $?

$(TMP_DIR)\tkWinTest.obj: $(WIN_DIR)\tkWinTest.c
	$(cc32) $(appcflags_nostubs) -Fo$@ $?

$(TMP_DIR)\tkSquare.obj: $(GENERICDIR)\tkSquare.c
	$(cc32) $(appcflags_nostubs) -Fo$@ $?

# Note: Static builds now always mandate statically linking Tcl registry etc.
$(TMP_DIR)\winMain.obj: $(WIN_DIR)\winMain.c
	$(cc32) $(appcflags_nostubs) /DUNICODE /D_UNICODE \
	    /DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \
	    /DTCL_USE_STATIC_PACKAGES=$(STATIC_BUILD) \
	    -Fo$@ $?

$(TMP_DIR)\tkMain2.obj: $(GENERICDIR)\tkMain.c
	$(cc32) $(pkgcflags) /DUNICODE /D_UNICODE -Fo$@ $?

# The following objects are part of the stub library and should not
# be built as DLL objects but none of the symbols should be exported
664
665
666
667
668
669
670
671

672
673

674

675
676
677
678
679
680
681
682
683
684
685
686
687


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
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765







-
+

-
+

+













+
+








+







	@$(CPY) "$(TKSTUBLIB)" "$(LIB_INSTALL_DIR)\"
!if !$(STATIC_BUILD)
	@echo creating package index
	@type << > $(OUT_DIR)\pkgIndex.tcl
if {[catch {package present Tcl 8.6-}]} { return }
if {($$::tcl_platform(platform) eq "unix") && ([info exists ::env(DISPLAY)]
	|| ([info exists ::argv] && ("-display" in $$::argv)))} {
    package ifneeded Tk $(TK_PATCH_LEVEL) [list load [file join $$dir .. .. bin libtk$(DOTVERSION).dll] Tk]
    package ifneeded tk $(TK_PATCH_LEVEL) [list load [file normalize [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 normalize [file join $$dir .. .. bin $(TKLIBNAME)]]]
}
package ifneeded Tk $(TK_PATCH_LEVEL) [list package require -exact tk $(TK_PATCH_LEVEL)]
<<
	@$(CPY) $(OUT_DIR)\pkgIndex.tcl "$(SCRIPT_INSTALL_DIR)\"
!endif

#"

install-libraries:
	@echo installing Tk headers
	@$(CPY) "$(GENERICDIR)\tk.h" "$(INCLUDE_INSTALL_DIR)\"
	@$(CPY) "$(GENERICDIR)\tkDecls.h" "$(INCLUDE_INSTALL_DIR)\"
	@$(CPY) "$(GENERICDIR)\tkPlatDecls.h" "$(INCLUDE_INSTALL_DIR)\"
	@$(CPY) "$(GENERICDIR)\tkIntXlibDecls.h" "$(INCLUDE_INSTALL_DIR)\"
	@$(CPY) "$(XLIBDIR)\X11\*.h" "$(INCLUDE_INSTALL_DIR)\X11\"
	@$(CPY) "$(TKSCRIPTZIP)" "$(LIB_INSTALL_DIR)"
!if !$(TK_EMBED_SCRIPTS)
	@echo installing script library
	@$(CPY) "$(LIBDIR)\*" "$(SCRIPT_INSTALL_DIR)\"
	@echo installing theme library
	@$(CPY) "$(LIBDIR)\ttk\*" "$(SCRIPT_INSTALL_DIR)\ttk\"
	@echo installing images
	@$(CPY) "$(LIBDIR)\images\*" "$(SCRIPT_INSTALL_DIR)\images\"
	@echo installing language files
	@$(CPY) "$(LIBDIR)\msgs\*" "$(SCRIPT_INSTALL_DIR)\msgs\"
!endif
	@echo installing demos
	@$(CPY) "$(DEMODIR)\*" "$(DEMO_INSTALL_DIR)\"
	@$(CPY) "$(DEMODIR)\images\*" "$(DEMO_INSTALL_DIR)\images\"

#"

#---------------------------------------------------------------------
716
717
718
719
720
721
722





779
780
781
782
783
784
785
786
787
788
789
790







+
+
+
+
+
	@echo Removing $(WISH) ...
	@if exist $(WISH) del $(WISH)
	@echo Removing $(TKTEST) ...
	@if exist $(TKTEST) del $(TKTEST)
	@echo Removing $(TKSTUBLIB) ...
	@if exist $(TKSTUBLIB) del $(TKSTUBLIB)

.PHONY:

# Local Variables:
# mode: makefile
# End:

Changes to win/nmakehlp.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






-
-
+
+







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

Changes to win/rc/tk.rc.

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







-
+







    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 2001 ActiveState Corporation, et al\0"
            VALUE "ProductName", "Tk " TK_VERSION " for Windows\0"
            VALUE "ProductVersion", TK_PATCH_LEVEL
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200

Changes to win/rc/wish.rc.

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







-
+







    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 2000 ActiveState Corporation, et al\0"
            VALUE "ProductName", "Tk " TK_VERSION " for Windows\0"
            VALUE "ProductVersion", TK_PATCH_LEVEL
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200

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







-
+







!if "$(PROJECT)" == "tcl"
!error The rules-ext.vc file is not intended for Tcl itself.
!endif

# We extract version numbers using the nmakehlp program. For now use
# the local copy of nmakehlp. Once we locate Tcl, we will use that
# one if it is newer.
!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul]
!if [$(CC) -nologo -DNDEBUG "nmakehlp.c" -link -subsystem:console > nul]
!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 = 9

# 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)" == ""
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
411
412
413
414
415
416
417



418
419
420
421
422
423
424







-
-
-







#     compiler version 1200. This is kept only for legacy reasons as it
#     does not make sense for recent Microsoft compilers. Only used for
#     output directory names.
# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target
# NATIVE_ARCH - set to IX86 or AMD64 for the host machine
# MACHINE - same as $(ARCH) - legacy
# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed
# CFG_ENCODING - set to an character encoding.
#   TBD - this is passed to compiler as TCL_CFGVAL_ENCODING but can't
#   see where it is used

cc32		= $(CC)   # built-in default.
link32		= link
lib32		= lib
rc32		= $(RC)   # built-in default.

#----------------------------------------------------------------
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517

518
519
520
521
522
523
524
496
497
498
499
500
501
502




503
504
505
506
507
508
509

510
511
512
513
514
515
516
517







-
-
-
-







-
+








# Since MSVC8 we must deal with manifest resources.
!if $(VCVERSION) >= 1400
_VC_MANIFEST_EMBED_EXE=if exist [email protected] mt -nologo -manifest [email protected] -outputresource:$@;1
_VC_MANIFEST_EMBED_DLL=if exist [email protected] mt -nologo -manifest [email protected] -outputresource:$@;2
!endif

!ifndef CFG_ENCODING
CFG_ENCODING	= \"cp1252\"
!endif

################################################################
# 4. Build the nmakehlp program
# This is a helper app we need to overcome nmake's limiting
# environment. We will call out to it to get various bits of
# information about supported compiler options etc.
#
# Tcl itself will always use the nmakehlp.c program which is
# in its own source. This is the "master" copy and kept updated.
# in its own source. It will be kept updated there.
#
# Extensions built against an installed Tcl will use the installed
# copy of Tcl's nmakehlp.c if there is one and their own version
# otherwise. In the latter case, they would also be using their own
# rules.vc. Note that older versions of Tcl do not install nmakehlp.c
# or rules.vc.
#
655
656
657
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
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







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

-
+













+

-
-
+
+







# 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)" 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) 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)
727
728
729
730
731
732
733
734

735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751

752
753
754
755
756
757
758
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







-
+
















-
+







!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
839
840
841
842
843
844
845
846

847
848
849
850
851
852
853
955
956
957
958
959
960
961

962
963
964
965
966
967
968
969







-
+







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
869
870
871
872
873
874
875
876

877
878
879
880
881
882
883
985
986
987
988
989
990
991

992
993
994
995
996
997
998
999







-
+







!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
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
1017
1018
1019
1020
1021
1022
1023





























































































1024
1025
1026
1027
1028
1029
1030







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







!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.,
#
1039
1040
1041
1042
1043
1044
1045
1046

1047
1048
1049
1050
1051
1052
1053
1062
1063
1064
1065
1066
1067
1068

1069
1070
1071
1072
1073
1074
1075
1076







-
+







!if "$(MACHINE)" != "IX86"
BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
!endif
!if $(VCVER) > 6
BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
!endif

!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
!if !$(DEBUG) || $(TCL_VERSION) > 86 || $(DEBUG) && $(UNCHECKED)
SUFX	    = $(SUFX:g=)
!endif

TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX

!if !$(STATIC_BUILD)
TMP_DIRFULL = $(TMP_DIRFULL:Static=)
1090
1091
1092
1093
1094
1095
1096

1097

1098












1099

1100
1101
1102
1103
1104

1105
1106
1107
1108
1109
1110
1111
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







+

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

+





+







!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
!if "$(TCL_PATCH_LETTER)" == "."
TCLSCRIPTZIPNAME = libtcl_$(TCL_MAJOR_VERSION)_$(TCL_MINOR_VERSION)_$(TCL_RELEASE_SERIAL).zip
!else
TCLSCRIPTZIPNAME = libtcl_$(TCL_MAJOR_VERSION)_$(TCL_MINOR_VERSION)_$(TCL_PATCH_LETTER)$(TCL_RELEASE_SERIAL).zip
!endif
!if "$(TK_PATCH_LETTER)" == "."
TKSCRIPTZIPNAME = libtk_$(TK_MAJOR_VERSION)_$(TK_MINOR_VERSION)_$(TK_RELEASE_SERIAL).zip
!else
TKSCRIPTZIPNAME = libtk_$(TK_MAJOR_VERSION)_$(TK_MINOR_VERSION)_$(TK_PATCH_LETTER)$(TK_RELEASE_SERIAL).zip
!endif

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

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

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







-
+
+














+
+

+










+
+

+







TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX).lib

!if $(DOING_TK)
WISH 		= $(OUT_DIR)\$(WISHNAME)
TKSTUBLIB	= $(OUT_DIR)\$(TKSTUBLIBNAME)
TKIMPLIB	= $(OUT_DIR)\$(TKIMPLIBNAME)
TKLIB		= $(OUT_DIR)\$(TKLIBNAME)
TK_INCLUDES    = -I"$(WIN_DIR)" -I"$(GENERICDIR)"
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
1288
1289
1290
1291
1292
1293
1294
1295
1296


1297
1298
1299
1300
1301
1302
1303
1335
1336
1337
1338
1339
1340
1341


1342
1343
1344
1345
1346
1347
1348
1349
1350







-
-
+
+







# 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	= /DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) /DSTDC_HEADERS
!if $(VCVERSION) >= 1600
OPTDEFINES	= /DSTDC_HEADERS
!if $(VCVERSION) > 1600
OPTDEFINES	= $(OPTDEFINES) /DHAVE_STDINT_H=1
!else
OPTDEFINES	= $(OPTDEFINES) /DMP_NO_STDINT=1
!endif
!if $(VCVERSION) >= 1800
OPTDEFINES	= $(OPTDEFINES) /DHAVE_INTTYPES_H=1 /DHAVE_STDBOOL_H=1
!endif
1459
1460
1461
1462
1463
1464
1465
1466

1467
1468
1469
1470
1471
1472
1473
1506
1507
1508
1509
1510
1511
1512

1513
1514
1515
1516
1517
1518
1519
1520







-
+







# 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
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
1529
1530
1531
1532
1533
1534
1535












1536
1537
1538
1539
1540
1541
1542







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







!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.
1603
1604
1605
1606
1607
1608
1609


1610
1611
1612
1613
1614
1615
1616
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653







+
+







	@$(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:
	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
1665
1666
1667
1668
1669
1670
1671
1672

1673
1674
1675
1676
1677
1678
1679
1702
1703
1704
1705
1706
1707
1708

1709
1710
1711
1712
1713
1714
1715
1716







-
+







	@if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
	$(DEBUGGER) $(TCLSH)

# Generation of Windows version resource
!ifdef RCFILE

# Note: don't use $** in below rule because there may be other dependencies
# and only the "master" rc must be passed to the resource compiler
# and only the "main" rc must be passed to the resource compiler
$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
	$(RESCMD) $(RCDIR)\$(PROJECT).rc

!else

# If parent makefile has not defined a resource definition file,
# we will generate one from standard template.
1719
1720
1721
1722
1723
1724
1725
1726

1727
1728
1729
1730
1731
1732
1733
1756
1757
1758
1759
1760
1761
1762

1763
1764
1765
1766
1767
1768
1769
1770







-
+








!ifndef DISABLE_IMPLICIT_RULES
DISABLE_IMPLICIT_RULES = 0
!endif

!if !$(DISABLE_IMPLICIT_RULES)
# Implicit rule definitions - only for building library objects. For stubs and
# main application, the master makefile should define explicit rules.
# main application, the makefile should define explicit rules.

{$(ROOT)}.c{$(TMP_DIR)}.obj::
	$(CCPKGCMD) @<<
$<
<<

{$(WIN_DIR)}.c{$(TMP_DIR)}.obj::
1767
1768
1769
1770
1771
1772
1773
1774
1775


1776
1777
1778
1779
1780
1781
1782
1804
1805
1806
1807
1808
1809
1810


1811
1812
1813
1814
1815
1816
1817
1818
1819







-
-
+
+







!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/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 )
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
276
277
278
279
280
281
282









283
284
285
286
287
288
289







-
-
-
-
-
-
-
-
-








    if test -f $TCL_BIN_DIR/Makefile ; then
        TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
        TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
        TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
    fi

    #
    # eval is required to do the TCL_DBGX substitution
    #

    eval "TCL_ZIP_FILE=\"${TCL_ZIP_FILE}\""
    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)
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
354
355
356
357
358
359
360








361
362
363
364
365
366
367







-
-
-
-
-
-
-
-







#------------------------------------------------------------------------

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?])
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
389
390
391
392
393
394
395

396
397
398
399
400
401
402
403
404
405

406
407
408
409
410
411
412

413
414
415
416
417
418
419







-










-







-







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

471
472
473
474
475
476
477

478
479
480
481
482
483
484
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465







+







# 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
525
526
527
528
529
530
531
532

533
534
535
536
537
538



539
540
541
542
543
544
545
506
507
508
509
510
511
512

513
514
515
516



517
518
519
520
521
522
523
524
525
526







-
+



-
-
-
+
+
+







    # which requires x86|amd64|ia64.
    MACHINE="X86"

    if test "$GCC" = "yes"; then

      AC_CACHE_CHECK(for cross-compile version of gcc,
	ac_cv_cross,
	AC_TRY_COMPILE([
	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"
592
593
594
595
596
597
598
599

600
601
602
603
604
605



606
607
608
609
610
611
612
613
614

615
616
617

618
619
620


621
622
623
624
625
626












627
628
629
630
631
632
633
573
574
575
576
577
578
579

580
581
582
583



584
585
586
587
588
589
590
591
592
593
594

595
596
597

598



599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625







-
+



-
-
-
+
+
+








-
+


-
+
-
-
-
+
+






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







    # 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

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

    AC_MSG_CHECKING([compiler flags])
    if test "${GCC}" = "yes" ; then
	SHLIB_LD=""
	SHLIB_LD_LIBS='${LIBS}'
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
639
640
641
642
643
644
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







-
+













-
+







-
+


-
-
-
+
+
+






-
+








-
+







	LIBPREFIX="lib"

	if test "${SHARED_BUILD}" = "0" ; then
	    # static
            AC_MSG_RESULT([using static flags])
	    runtime=
	    LIBRARIES="\${STATIC_LIBRARIES}"
	    EXESUFFIX="s\${DBGX}.exe"
	    EXESUFFIX="s.exe"
	else
	    # dynamic
            AC_MSG_RESULT([using shared flags])

	    # ad-hoc check to see if CC supports -shared.
	    if "${CC}" -shared 2>&1 | egrep ': -shared not supported' >/dev/null; then
		AC_MSG_ERROR([${CC} does not support the -shared option.
                You will need to upgrade to a newer version of the toolchain.])
	    fi

	    runtime=
	    # Add SHLIB_LD_LIBS to the Make rule, not here.

	    EXESUFFIX="\${DBGX}.exe"
	    EXESUFFIX=".exe"
	    LIBRARIES="\${SHARED_LIBRARIES}"
	fi
	# Link with gcc since ld does not link to default libs like
	# -luser32 and -lmsvcrt by default.
	SHLIB_LD='${CC} -shared'
	SHLIB_LD_LIBS='${LIBS}'
	MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -o \[$]@ ${extra_ldflags} \
	    -Wl,--out-implib,\$(patsubst %.dll,lib%.a,\[$]@)"
	    -Wl,--out-implib,\$(patsubst %.dll,lib%.dll.a,\[$]@)"
	# DLLSUFFIX is separate because it is the building block for
	# users of tclConfig.sh that may build shared or static.
	DLLSUFFIX="\${DBGX}.dll"
	LIBSUFFIX="\${DBGX}.a"
	LIBFLAGSUFFIX="\${DBGX}"
	DLLSUFFIX=".dll"
	LIBSUFFIX=".a"
	LIBFLAGSUFFIX=""
	SHLIB_SUFFIX=.dll

	EXTRA_CFLAGS="${extra_cflags}"

	CFLAGS_DEBUG=-g
	CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
	CFLAGS_WARNING="-Wall -Wextra -Wwrite-strings -Wpointer-arith"
	CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith -finput-charset=UTF-8"
	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} -Wc++-compat -fextended-identifiers"
		;;
	esac

	# Specify the CC output file names based on the target name
	CC_OBJNAME="-o \[$]@"
	CC_EXENAME="-o \[$]@"

725
726
727
728
729
730
731
732

733
734
735
736
737
738



739
740
741
742
743



744
745
746
747
748
749
750
751
752
753

754
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
717
718
719
720
721
722
723

724
725
726
727



728
729
730
731
732



733
734
735
736
737
738
739
740
741
742
743
744

745
746
747
748
749
750
751

752
753
754
755
756
757
758
759
760
761
762
763



764
765
766
767
768
769
770
771
772
773







-
+



-
-
-
+
+
+


-
-
-
+
+
+









-
+






-
+











-
-
-
+
+
+







		AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
		;;
	    ia64)
		MACHINE="IA64"
		AC_MSG_RESULT([   Using 64-bit $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])
	    runtime=-MT
	    LIBRARIES="\${STATIC_LIBRARIES}"
	    EXESUFFIX="s\${DBGX}.exe"
	    EXESUFFIX="s.exe"
	else
	    # dynamic
            AC_MSG_RESULT([using shared flags])
	    runtime=-MD
	    # Add SHLIB_LD_LIBS to the Make rule, not here.
	    LIBRARIES="\${SHARED_LIBRARIES}"
	    EXESUFFIX="\${DBGX}.exe"
	    EXESUFFIX=".exe"
	    case "x`echo \${VisualStudioVersion}`" in
		x1[[4-9]]*)
		    lflags="${lflags} -nodefaultlib:libucrt.lib"
		    ;;
		*)
		    ;;
	    esac
	fi
	MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -out:\[$]@"
	# DLLSUFFIX is separate because it is the building block for
	# users of tclConfig.sh that may build shared or static.
	DLLSUFFIX="\${DBGX}.dll"
	LIBSUFFIX="\${DBGX}.lib"
	LIBFLAGSUFFIX="\${DBGX}"
	DLLSUFFIX=".dll"
	LIBSUFFIX=".lib"
	LIBFLAGSUFFIX=""

	if test "$do64bit" != "no" ; then
	    case "$do64bit" in
		amd64|x64|yes)
		    MACHINE="AMD64" ; # assume AMD64 as default 64-bit build
		    ;;
		ia64)
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
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







-
+














-
-
-
-
+
+
+
+














-
+



-
+

-
-
-
+
+
+












-
+




-
+



-
-
-
+
+
+














-
+
-


-
-
-
+
+
+












+







    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.
#
1065
1066
1067
1068
1069
1070
1071
1072

1073
1074
1075
1076
1077
1078
1079
1057
1058
1059
1060
1061
1062
1063

1064
1065
1066
1067
1068
1069
1070
1071







-
+







# Results
#	Subst's the following values:
#		BUILD_TCLSH
#------------------------------------------------------------------------

AC_DEFUN([SC_BUILD_TCLSH], [
    AC_MSG_CHECKING([for tclsh in Tcl build directory])
    BUILD_TCLSH=${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}
    BUILD_TCLSH=${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${EXEEXT}
    AC_MSG_RESULT($BUILD_TCLSH)
    AC_SUBST(BUILD_TCLSH)
])

#--------------------------------------------------------------------
# SC_TCL_CFG_ENCODING	TIP #59
#
1093
1094
1095
1096
1097
1098
1099
1100
1101

1102
1103
1104
1105
1106
1107
1108
1085
1086
1087
1088
1089
1090
1091


1092
1093
1094
1095
1096
1097
1098
1099







-
-
+








AC_DEFUN([SC_TCL_CFG_ENCODING], [
    AC_ARG_WITH(encoding, [  --with-encoding         encoding for configuration values], with_tcencoding=${withval})

    if test x"${with_tcencoding}" != x ; then
	AC_DEFINE_UNQUOTED(TCL_CFGVAL_ENCODING,"${with_tcencoding}")
    else
	# Default encoding on windows is not "iso8859-1"
	AC_DEFINE(TCL_CFGVAL_ENCODING,"cp1252")
	AC_DEFINE(TCL_CFGVAL_ENCODING,"utf-8")
    fi
])

#--------------------------------------------------------------------
# SC_EMBED_MANIFEST
#
#	Figure out if we can embed the manifest where necessary
1116
1117
1118
1119
1120
1121
1122
1123

1124
1125
1126
1127
1128
1129
1130
1107
1108
1109
1110
1111
1112
1113

1114
1115
1116
1117
1118
1119
1120
1121







-
+







#		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" \

Changes to win/tkConfig.sh.in.

21
22
23
24
25
26
27

28
29


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


29
30
31
32
33
34
35
36
37







+
-
-
+
+








# -D flags for use with the C compiler.
TK_DEFS='@DEFS@'

# Flag, 1: we built a shared lib, 0 we didn't
TK_SHARED_BUILD=@TK_SHARED_BUILD@

# TK_DBGX used to be used to distinguish debug vs. non-debug builds.
# This indicates if Tk was build with debugging symbols
TK_DBGX=@TK_DBGX@
# This was a righteous pain so the core doesn't do that any more.
TK_DBGX=

# The name of the Tk library (may be either a .a file or a shared library):
TK_LIB_FILE='@TK_LIB_FILE@'

# Additional libraries to use when linking Tk.
TK_LIBS='@LIBS@ @LIBS_GUI@'

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
36
37
38
39






-
+


















-
+


-
+


-
+







/*
 * 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
 * support Windows XP, but the Vista-specifics are tested at runtime.
 */

#ifndef WINVER
#   define WINVER 0x0600
#   define WINVER 0x0601
#endif
#ifndef _WIN32_WINNT
#   define _WIN32_WINNT 0x0600
#   define _WIN32_WINNT 0x0601
#endif
#ifndef _WIN32_IE
#   define _WIN32_IE 0x0700
#   define _WIN32_IE 0x0800
#endif

#ifndef _TK
#include <tk.h>
#endif

#define WIN32_LEAN_AND_MEAN

Changes to win/tkWin32Dll.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





-
+







/*
 * tkWin32Dll.c --
 *
 *	This file contains a stub dll entry point.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 * Copyright © 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"
#ifndef STATIC_BUILD
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







-
+







	     * 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 © 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"

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 © 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"

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 © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 1998-2000 Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"
#include "tkSelect.h"

Changes to win/tkWinColor.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





-
-
+
+







/*
 * tkWinColor.c --
 *
 *	Functions to map color names to system color values.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 * Copyright (c) 1994 Software Research Associates, Inc.
 * Copyright © 1995 Sun Microsystems, Inc.
 * Copyright © 1994 Software Research Associates, 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 "tkColor.h"
54
55
56
57
58
59
60

61
62
63
64
65
66
67
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68







+







    {"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}
};

/*

Changes to win/tkWinConfig.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






-
+







/*
 * tkWinConfig.c --
 *
 *	This module implements the Windows system defaults for the
 *	configuration package.
 *
 * Copyright (c) 1997 by Sun Microsystems, Inc.
 * Copyright © 1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"

Changes to win/tkWinCursor.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





-
+







/*
 * tkWinCursor.c --
 *
 *	This file contains Win32 specific cursor related routines.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 * Copyright © 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"

100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
100
101
102
103
104
105
106

107
108
109
110
111
112
113
114







-
+







    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;

Changes to win/tkWinDefault.h.

154
155
156
157
158
159
160
161

162
163
164
165
166
167
168
154
155
156
157
158
159
160

161
162
163
164
165
166
167
168







-
+







#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		"#b3b3b3"
#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"

Changes to win/tkWinDialog.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





-
+







/*
 * tkWinDialog.c --
 *
 *	Contains the Windows implementation of the common dialog boxes.
 *
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 * Copyright © 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"
#include "tkFileFilter.h"
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
586
587
588
589
590
591
592

593























































594
595
596
597
598
599
600







-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







			    Tcl_DString *dsPtr, Tcl_Obj *initialPtr,
			    int *indexPtr);
static UINT APIENTRY	OFNHookProc(HWND hdlg, UINT uMsg, WPARAM wParam,
			    LPARAM lParam);
static LRESULT CALLBACK MsgBoxCBTProc(int nCode, WPARAM wParam, LPARAM lParam);
static void		SetTkDialog(ClientData clientData);
static const char *ConvertExternalFilename(LPCWSTR, Tcl_DString *);
static void             LoadShellProcs(void);


/* Definitions of dynamically loaded Win32 calls */
typedef HRESULT (STDAPICALLTYPE SHCreateItemFromParsingNameProc)(
    PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv);
struct ShellProcPointers {
    SHCreateItemFromParsingNameProc *SHCreateItemFromParsingName;
} ShellProcs;


/*
 *-------------------------------------------------------------------------
 *
 * LoadShellProcs --
 *
 *     Some shell functions are not available on older versions of
 *     Windows. This function dynamically loads them and stores pointers
 *     to them in ShellProcs. Any function that is not available has
 *     the corresponding pointer set to NULL.
 *
 *     Note this call never fails. Unavailability of a function is not
 *     a reason for failure. Caller should check whether a particular
 *     function pointer is NULL or not. Once loaded a function stays
 *     forever loaded.
 *
 *     XXX - we load the function pointers into global memory. This implies
 *     there is a potential (however small) for race conditions between
 *     threads. However, Tk is in any case meant to be loaded in exactly
 *     one thread so this should not be an issue and saves us from
 *     unnecessary bookkeeping.
 *
 * Return value:
 *     None.
 *
 * Side effects:
 *     ShellProcs is populated.
 *-------------------------------------------------------------------------
 */
static void LoadShellProcs(void)
{
    static HMODULE shell32_handle = NULL;

    if (shell32_handle != NULL) {
	return; /* We have already been through here. */
    }

    shell32_handle = GetModuleHandleW(L"shell32.dll");
    if (shell32_handle == NULL) { /* Should never happen but check anyways. */
	return;
    }

    ShellProcs.SHCreateItemFromParsingName = (SHCreateItemFromParsingNameProc*)
	    (void *)GetProcAddress(shell32_handle, "SHCreateItemFromParsingName");
}


/*
 *-------------------------------------------------------------------------
 *
 * EatSpuriousMessageBugFix --
 *
 *	In the file open/save dialog, double clicking on a list item causes
 *	the dialog box to close, but an unwanted WM_LBUTTONUP message is sent
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
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







-
+














-
+







	{"-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;
    /* 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;
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
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







-
+
-
-
-
-
+
+

-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
+
+

-
-
-
-
-
+
+
+
+
+
-







{
    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;
	tsdPtr->newFileDialogsState = FDLG_STATE_USE_OLD;
        LoadShellProcs();
        if (ShellProcs.SHCreateItemFromParsingName != NULL) {
            hr = CoInitialize(0);
            /* XXX - need we schedule CoUninitialize at thread shutdown ? */
	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);
}

/*
 *----------------------------------------------------------------------
1409
1410
1411
1412
1413
1414
1415
1416

1417
1418
1419
1420
1421
1422
1423
1349
1350
1351
1352
1353
1354
1355

1356
1357
1358
1359
1360
1361
1362
1363







-
+







        normPath = Tcl_FSGetNormalizedPath(interp, iniDirPath);
        /* XXX - Note on failures do not raise error, simply ignore ini dir */
        if (normPath) {
            LPCWSTR nativePath;
            Tcl_IncrRefCount(normPath);
            nativePath = (LPCWSTR)Tcl_FSGetNativePath(normPath); /* Points INTO normPath*/
            if (nativePath) {
                hr = ShellProcs.SHCreateItemFromParsingName(
                hr = SHCreateItemFromParsingName(
                    nativePath, NULL,
                    &IIDIShellItem, (void **) &dirIf);
                if (SUCCEEDED(hr)) {
                    /* Note we use SetFolder, not SetDefaultFolder - see MSDN */
                    fdlgIf->lpVtbl->SetFolder(fdlgIf, dirIf); /* Ignore errors */
                }
            }
2117
2118
2119
2120
2121
2122
2123
2124

2125
2126
2127
2128
2129
2130
2131
2057
2058
2059
2060
2061
2062
2063

2064
2065
2066
2067
2068
2069
2070
2071







-
+








    } else {
	TkSizeT 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"
	 *
2707
2708
2709
2710
2711
2712
2713
2714

2715
2716
2717

2718
2719
2720
2721
2722
2723
2724
2647
2648
2649
2650
2651
2652
2653

2654
2655
2656

2657
2658
2659
2660
2661
2662
2663
2664







-
+


-
+







	 * -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: {
	/*
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
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







-
+





-
+

















-
+







	if (IsWindow(hwndCtrl)) {
	    EnableWindow(hwndCtrl, FALSE);
	}
	hwndCtrl = GetDlgItem(hwndDlg, 0x473);
	if (IsWindow(hwndCtrl)) {
	    EnableWindow(hwndCtrl, FALSE);
	}
	TkSendVirtualEvent(phd->parent, "TkFontchooserVisibility", NULL);
	Tk_SendVirtualEvent(phd->parent, "TkFontchooserVisibility", NULL);
	return 1; /* we handled the message */
    }

    if (WM_DESTROY == msg) {
	phd->hwnd = NULL;
	TkSendVirtualEvent(phd->parent, "TkFontchooserVisibility", NULL);
	Tk_SendVirtualEvent(phd->parent, "TkFontchooserVisibility", NULL);
	return 0;
    }

    /*
     * Handle apply button by calling the provided command script as a
     * background evaluation (ie: errors dont come back here).
     */

    if (WM_COMMAND == msg && LOWORD(wParam) == 1026) {
	LOGFONTW lf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0}};
	HDC hdc = GetDC(hwndDlg);

	SendMessageW(hwndDlg, WM_CHOOSEFONT_GETLOGFONT, 0, (LPARAM) &lf);
	if (phd && phd->cmdObj) {
	    ApplyLogfont(phd->interp, phd->cmdObj, hdc, &lf);
	}
	if (phd && phd->parent) {
	    TkSendVirtualEvent(phd->parent, "TkFontchooserFontChanged", NULL);
	    Tk_SendVirtualEvent(phd->parent, "TkFontchooserFontChanged", NULL);
	}
	return 1;
    }
    return 0; /* pass on for default processing */
}

/*
3521
3522
3523
3524
3525
3526
3527
3528

3529
3530
3531
3532
3533
3534
3535
3461
3462
3463
3464
3465
3466
3467

3468
3469
3470
3471
3472
3473
3474
3475







-
+







    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) {
		TkSendVirtualEvent(hdPtr->parent, "TkFontchooserFontChanged", NULL);
		Tk_SendVirtualEvent(hdPtr->parent, "TkFontchooserFontChanged", NULL);
	    }
	}
	Tcl_SetServiceMode(oldMode);
	EnableWindow(cf.hwndOwner, 1);
    }

    ReleaseDC(cf.hwndOwner, hdc);

Changes to win/tkWinDraw.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






-
-
+
+







/*
 * tkWinDraw.c --
 *
 *	This file contains the Xlib emulation functions pertaining to actually
 *	drawing objects on a window.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 * Copyright (c) 1994 Software Research Associates, Inc.
 * Copyright © 1995 Sun Microsystems, Inc.
 * Copyright © 1994 Software Research Associates, 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"

Changes to win/tkWinEmbed.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








-
+







/*
 * tkWinEmbed.c --
 *
 *	This file contains platform specific procedures for Windows platforms
 *	to provide basic operations needed for application embedding (where
 *	one application can use as its main window an internal window from
 *	another application).
 *
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 * Copyright © 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"

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 © 1994 Software Research Associates, Inc.
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 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"
1357
1358
1359
1360
1361
1362
1363
1364




1365
1366
1367
1368
1369
1370
1371
1357
1358
1359
1360
1361
1362
1363

1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374







-
+
+
+
+







 *---------------------------------------------------------------------------
 *
 * TkpDrawCharsInContext --
 *
 *	Draw a string of characters on the screen like Tk_DrawChars(), but
 *	with access to all the characters on the line for context. On Windows
 *	this context isn't consulted, so we just call Tk_DrawChars().
 *
  *
 *      Note: TK_DRAW_IN_CONTEXT being currently defined only on macOS, this
 *            function is unused (and possibly unfinished). See [7655f65ae7].
*
 * Results:
 *	None.
 *
 * Side effects:
 *	Information gets drawn on the screen.
 *
 *---------------------------------------------------------------------------
1394
1395
1396
1397
1398
1399
1400































1401
1402
1403
1404
1405
1406
1407
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







{
    int widthUntilStart;

    Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart);
    Tk_DrawChars(display, drawable, gc, tkfont, source + rangeStart,
	    rangeLength, x+widthUntilStart, y);
}

void
TkpDrawAngledCharsInContext(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn; must
				 * be the same as font used in GC. */
    const char * source,	/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that is
				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int rangeStart,		/* Index of first byte to draw. */
    int rangeLength,		/* Length of range to draw in bytes. */
    double x, double y,		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
    double angle)		/* What angle to put text at, in degrees. */
{
    int widthUntilStart;
    double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0);
    (void) numBytes; /*unused*/

    Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart);
    TkDrawAngledChars(display, drawable, gc, tkfont, source + rangeStart,
	    rangeLength, x+cosA*widthUntilStart, y-sinA*widthUntilStart, angle);
}

/*
 *-------------------------------------------------------------------------
 *
 * MultiFontTextOut --
 *
 *	Helper function for Tk_DrawChars. Draws characters, using the various
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
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







-
+

-
+



















-
+







	 */

	if ((thisSubFontPtr != lastSubFontPtr) || (p-source > 200)) {
	    if (p > source) {
		familyPtr = lastSubFontPtr->familyPtr;
 		Tcl_UtfToExternalDString(familyPtr->encoding, source,
			(int) (p - source), &runString);
		familyPtr->textOutProc(hdc, x-(tm.tmOverhang/2), y,
		familyPtr->textOutProc(hdc, (int)(x-(double)tm.tmOverhang/2.0), y,
			(WCHAR *)Tcl_DStringValue(&runString),
			Tcl_DStringLength(&runString)>>familyPtr->isWideFont);
			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-(tm.tmOverhang/2), y,
	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);
}

Added win/tkWinIco.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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
 * tkWinIco.c --
 *
 *	This file contains functions for icon-manipulation routines
 *      in Windows.
 *
 * Copyright © 1995-1996 Microsoft Corp.
 * Copyright © 1998 Brueckner & Jarosch Ing.GmbH, Erfurt, Germany
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinIco.h"

/*
 *----------------------------------------------------------------------
 *
 * DIBNumColors --
 *
 *	Calculates the number of entries in the color table, given by LPSTR
 *	lpbi - pointer to the CF_DIB memory block. Used by titlebar icon code.
 *
 * Results:
 *	WORD - Number of entries in the color table.
 *
 *----------------------------------------------------------------------
 */

static WORD
DIBNumColors(
    LPSTR lpbi)
{
    WORD wBitCount;
    DWORD dwClrUsed;

    dwClrUsed = ((LPBITMAPINFOHEADER) lpbi)->biClrUsed;

    if (dwClrUsed) {
	return (WORD) dwClrUsed;
    }

    wBitCount = ((LPBITMAPINFOHEADER) lpbi)->biBitCount;

    switch (wBitCount) {
    case 1:
	return 2;
    case 4:
	return 16;
    case 8:
	return 256;
    default:
	return 0;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * PaletteSize --
 *
 *	Calculates the number of bytes in the color table, as given by LPSTR
 *	lpbi - pointer to the CF_DIB memory block. Used by titlebar icon code.
 *
 * Results:
 *	Number of bytes in the color table
 *
 *----------------------------------------------------------------------
 */
static WORD
PaletteSize(
    LPSTR lpbi)
{
    return (WORD) (DIBNumColors(lpbi) * sizeof(RGBQUAD));
}

/*
 *----------------------------------------------------------------------
 *
 * FindDIBits --
 *
 *	Locate the image bits in a CF_DIB format DIB, as given by LPSTR lpbi -
 *	pointer to the CF_DIB memory block. Used by titlebar icon code.
 *
 * Results:
 *	pointer to the image bits
 *
 * Side effects: None
 *
 *
 *----------------------------------------------------------------------
 */

LPSTR
FindDIBBits(
    LPSTR lpbi)
{
    return lpbi + *((LPDWORD) lpbi) + PaletteSize(lpbi);
}

/*
 *----------------------------------------------------------------------
 *
 * BytesPerLine --
 *
 *	Calculates the number of bytes in one scan line, as given by
 *	LPBITMAPINFOHEADER lpBMIH - pointer to the BITMAPINFOHEADER that
 *	begins the CF_DIB block. Used by titlebar icon code.
 *
 * Results:
 *	number of bytes in one scan line (DWORD aligned)
 *
 *----------------------------------------------------------------------
 */

DWORD
BytesPerLine(
    LPBITMAPINFOHEADER lpBMIH)
{
    return WIDTHBYTES(lpBMIH->biWidth * lpBMIH->biPlanes * lpBMIH->biBitCount);
}
/*
 *----------------------------------------------------------------------
 *
 * CreateIcoFromPhoto --
 *
 *	Create ico pointer from Tk photo block.
 *
 * Results:
 *	Icon image is created from a valid Tk photo image.
 *
 * Side effects:
 *	Icon is created.
 *
 *----------------------------------------------------------------------
 */

HICON
CreateIcoFromPhoto(
    int width,                  /* Width of image. */
    int height,                 /* Height of image. */
    Tk_PhotoImageBlock block)   /* Image block to convert. */
{
    int idx, bufferSize;
    union {unsigned char *ptr; void *voidPtr;} bgraPixel;
    union {unsigned char *ptr; void *voidPtr;} bgraMask;
    HICON hIcon;
    BITMAPINFO bmInfo;
    ICONINFO iconInfo;

    /*
     * Don't use CreateIcon to create the icon, as it requires color
     * bitmap data in device-dependent format. Instead we use
     * CreateIconIndirect which takes device-independent bitmaps and
     * converts them as required. Initialise icon info structure.
     */

    ZeroMemory(&iconInfo, sizeof(iconInfo));
    iconInfo.fIcon = TRUE;

    /*
     * Create device-independent color bitmap.
     */

    ZeroMemory(&bmInfo, sizeof bmInfo);
    bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmInfo.bmiHeader.biWidth = width;
    bmInfo.bmiHeader.biHeight = -height;
    bmInfo.bmiHeader.biPlanes = 1;
    bmInfo.bmiHeader.biBitCount = 32;
    bmInfo.bmiHeader.biCompression = BI_RGB;

    iconInfo.hbmColor = CreateDIBSection(NULL, &bmInfo, DIB_RGB_COLORS,
            &bgraPixel.voidPtr, NULL, 0);
    if (!iconInfo.hbmColor) {
        return NULL;
    }

    /*
     * Convert the photo image data into BGRA format (RGBQUAD).
     */

    bufferSize = height * width * 4;
    for (idx = 0 ; idx < bufferSize ; idx += 4) {
        bgraPixel.ptr[idx] = block.pixelPtr[idx+2];
        bgraPixel.ptr[idx+1] = block.pixelPtr[idx+1];
        bgraPixel.ptr[idx+2] = block.pixelPtr[idx+0];
        bgraPixel.ptr[idx+3] = block.pixelPtr[idx+3];
    }

    /*
     * Create a dummy mask bitmap. The contents of this don't appear to
     * matter, as CreateIconIndirect will setup the icon mask based on the
     * alpha channel in our color bitmap.
     */

    bmInfo.bmiHeader.biBitCount = 1;

    iconInfo.hbmMask = CreateDIBSection(NULL, &bmInfo, DIB_RGB_COLORS,
            &bgraMask.voidPtr, NULL, 0);
    if (!iconInfo.hbmMask) {
        DeleteObject(iconInfo.hbmColor);
        return NULL;
    }

    ZeroMemory(bgraMask.ptr, width*height/8);

    /*
     * Create an icon from the bitmaps.
     */

    hIcon = CreateIconIndirect(&iconInfo);
    DeleteObject(iconInfo.hbmColor);
    DeleteObject(iconInfo.hbmMask);
    if (hIcon == NULL) {
        return NULL;
    }

    return hIcon;
}
/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Added win/tkWinIco.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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
 * tkWinIco.h --
 *
 *	This file contains declarations for icon-manipulation routines
 *      in Windows.
 *
 * Copyright © 1995-1996 Microsoft Corp.
 * Copyright © 1998 Brueckner & Jarosch Ing.GmbH, Erfurt, Germany
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWin.h"
#include <windows.h>
#include <shellapi.h>

/*
 * These structures represent the contents of a icon, in terms of its image
 * or resource.
 */

typedef struct {
    UINT Width, Height, Colors;	/* Width, Height and bpp */
    LPBYTE lpBits;		/* Ptr to DIB bits */
    DWORD dwNumBytes;		/* How many bytes? */
    LPBITMAPINFO lpbi;		/* Ptr to header */
    LPBYTE lpXOR;		/* Ptr to XOR image bits */
    LPBYTE lpAND;		/* Ptr to AND image bits */
    HICON hIcon;		/* DAS ICON */
} ICONIMAGE, *LPICONIMAGE;

typedef struct {
    BOOL         bHasChanged;                     // Has image changed?
    TCHAR        szOriginalICOFileName[MAX_PATH]; // Original name
    TCHAR        szOriginalDLLFileName[MAX_PATH]; // Original name
    int          nNumImages;                      // How many images?
    ICONIMAGE    IconImages[1];                   // Image entries
} ICONRESOURCE, *LPICONRESOURCE;

/*
 * This structure is how we represent a block of the above items. We will
 * reallocate these structures according to how many images they need to
 * contain.
 */

typedef struct {
    int nNumImages;		/* How many images? */
    ICONIMAGE IconImages[1];	/* Image entries */
} BlockOfIconImages, *BlockOfIconImagesPtr;

/*
 * These two structures are used to read in icons from an 'icon directory'
 * (i.e. the contents of a .icr file, say). We only use these structures
 * temporarily, since we copy the information we want into a
 * BlockOfIconImages.
 */

typedef struct {
    BYTE bWidth;		/* Width of the image */
    BYTE bHeight;		/* Height of the image (times 2) */
    BYTE bColorCount;		/* Number of colors in image (0 if >=8bpp) */
    BYTE bReserved;		/* Reserved */
    WORD wPlanes;		/* Color Planes */
    WORD wBitCount;		/* Bits per pixel */
    DWORD dwBytesInRes;		/* How many bytes in this resource? */
    DWORD dwImageOffset;	/* Where in the file is this image */
} ICONDIRENTRY, *LPICONDIRENTRY;

typedef struct {
    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;

/*
 * Used in BytesPerLine
 */

#define WIDTHBYTES(bits)	((((bits) + 31)>>5)<<2)

/*
 * The following are implemented in tkWinIco.c and also used in tkWinWm.c and tkWinSysTray.c.
 */

DWORD BytesPerLine(LPBITMAPINFOHEADER lpBMIH);
LPSTR FindDIBBits(LPSTR lpbi);
HICON CreateIcoFromPhoto(int width, int height,
                        Tk_PhotoImageBlock block);


/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */



Changes to win/tkWinImage.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





-
+







/*
 * tkWinImage.c --
 *
 *	This file contains routines for manipulation full-color images.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 * Copyright © 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"

273
274
275
276
277
278
279
280

281
282
283
284
285
286
287
273
274
275
276
277
278
279

280
281
282
283
284
285
286
287







-
+







 *	Returns a newly allocated image containing the data from the given
 *	rectangle of the given drawable.
 *
 * Side effects:
 *	None.
 *
 * This procedure is adapted from the XGetImage implementation in TkNT. That
 * code is Copyright (c) 1994 Software Research Associates, Inc.
 * code is Copyright © 1994 Software Research Associates, Inc.
 *
 *----------------------------------------------------------------------
 */

static XImage *
XGetImageZPixmap(
    Display *display,

Changes to win/tkWinInit.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






-
+







/*
 * tkWinInit.c --
 *
 *	This file contains Windows-specific interpreter initialization
 *	functions.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"

34
35
36
37
38
39
40
41


42
43

44
45
46
47
48
49
50
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50
51
52







-
+
+


+







int
TkpInit(
    Tcl_Interp *interp)
{
    (void)interp;
    /*
     * This is necessary for static initialization, and is ok otherwise
     * because TkWinXInit flips a static bit to do its work just once.
     * because TkWinXInit flips a static bit to do its work just once. Also,
     * initialize the Windows systray command here.
     */

    WinIcoInit(interp);
    TkWinXInit(Tk_GetHINSTANCE());
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
120
121
122
123
124
125
126
127

128
129
130
131
132
133
134
122
123
124
125
126
127
128

129
130
131
132
133
134
135
136







-
+







#define TK_MAX_WARN_LEN 1024
    WCHAR titleString[TK_MAX_WARN_LEN];
    WCHAR *msgString; /* points to titleString, just after title, leaving space for ": " */
    int len; /* size of title, including terminating NULL */

    /* If running on Cygwin and we have a stderr channel, use it. */
#if !defined(STATIC_BUILD)
	if (tclStubsPtr->reserved9) {
	if (tclStubsPtr->tcl_CreateFileHandler) {
	Tcl_Channel errChannel = Tcl_GetStdChannel(TCL_STDERR);
	if (errChannel) {
	    Tcl_WriteChars(errChannel, title, -1);
	    Tcl_WriteChars(errChannel, ": ", 2);
	    Tcl_WriteChars(errChannel, msg, -1);
	    Tcl_WriteChars(errChannel, "\n", 1);
	    return;

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
210
211
212
213
214
215
216







217
218
219
220
221
222
223
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230







+
+
+
+
+
+
+








/*
 * The following is implemented in tkWinPointer.c and also used in tkWinWindow.c
 */

MODULE_SCOPE void		TkSetCursorPos(int x, int y);


/*
 * The following is implemented in tkWinSysTray.c
 */

MODULE_SCOPE  int       WinIcoInit (Tcl_Interp* interp);

/*
 * Common routines used in Windows implementation
 */
MODULE_SCOPE Tcl_Obj *	        TkWin32ErrorObj(HRESULT hrError);


/*

Changes to win/tkWinKey.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






-
+







/*
 * tkWinKey.c --
 *
 *	This file contains X emulation routines for keyboard related
 *	functions.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 * Copyright © 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"
#include "X11/XF86keysym.h"
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







-
+







    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*55 0x37*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*60 0x3C*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*65 0x41*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*70 0x46*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*75 0x4B*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*80 0x50*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*85 0x55*/
    NoSymbol, XK_Win_L, XK_Win_R, XK_App, NoSymbol, /*90 0x5A*/
    NoSymbol, XK_Super_L, XK_Super_R, XK_Menu, NoSymbol, /*90 0x5A*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*95 0x5F*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*100 0x64*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*105 0x69*/
    NoSymbol, NoSymbol, XK_F1, XK_F2, XK_F3, /*110 0x6E*/
    XK_F4, XK_F5, XK_F6, XK_F7, XK_F8, /*115 0x73*/
    XK_F9, XK_F10, XK_F11, XK_F12, XK_F13, /*120 0x78*/
    XK_F14, XK_F15, XK_F16, XK_F17, XK_F18, /*125 0x7D*/
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121







-
+







	if (ev->nbytes > 0) {
	    Tcl_ExternalToUtfDString(TkWinGetKeyInputEncoding(),
		    ev->trans_chars, ev->nbytes, dsPtr);
	}
    } else if (keyEv->send_event == -3) {

	/*
	 * Special case for WM_UNICHAR and win2000 multi-lingal IME input
	 * Special case for WM_UNICHAR and win2000 multilingual IME input
	 */

	len = TkUniCharToUtf(keyEv->keycode, buf);
	Tcl_DStringAppend(dsPtr, buf, len);
    } else {
	/*
	 * This is an event generated from generic code. It has no nchars or

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 © 1996-1998 Sun Microsystems, Inc.
 * Copyright © 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"
681
682
683
684
685
686
687
688

689
690
691
692
693
694
695
696
697
698
699

700
701
702
703
704
705
706
681
682
683
684
685
686
687

688
689
690
691
692
693
694
695
696
697
698

699
700
701
702
703
704
705
706







-
+










-
+







			    & MENU_SYSTEM_MENU)) {
		Tcl_DString ds;
		TkMenuReferences *menuRefPtr;
		TkMenu *systemMenuPtr = mePtr->childMenuRefPtr->menuPtr;

		Tcl_DStringInit(&ds);
		Tcl_DStringAppend(&ds,
			Tk_PathName(menuPtr->masterMenuPtr->tkwin), -1);
			Tk_PathName(menuPtr->mainMenuPtr->tkwin), -1);
		Tcl_DStringAppend(&ds, ".system", 7);

		menuRefPtr = TkFindMenuReferences(menuPtr->interp,
			Tcl_DStringValue(&ds));

		Tcl_DStringFree(&ds);

		if ((menuRefPtr != NULL)
			&& (menuRefPtr->menuPtr != NULL)
			&& (menuPtr->parentTopLevelPtr != NULL)
			&& (systemMenuPtr->masterMenuPtr
			&& (systemMenuPtr->mainMenuPtr
				== menuRefPtr->menuPtr)) {
		    HMENU systemMenuHdl = (HMENU) systemMenuPtr->platformData;
		    HWND wrapper = TkWinGetWrapperWindow(menuPtr
			    ->parentTopLevelPtr);

		    if (wrapper != NULL) {
			DestroyMenu(systemMenuHdl);
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
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







-
+
+

















-
+



-
+




-
+







	}
	break;

    case WM_MENUCHAR: {
	hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
		*plParam);
	if (hashEntryPtr != NULL) {
	    TkSizeT i, len, underline;
	    TkSizeT i, len;
	    int underline;
	    Tcl_Obj *labelPtr;
	    WCHAR *wlabel;
	    int menuChar;
	    Tcl_DString ds;

	    *plResult = 0;
	    menuPtr = (TkMenu *)Tcl_GetHashValue(hashEntryPtr);
	    /*
	     * Assume we have something directly convertable to Tcl_UniChar.
	     * True at least for wide systems.
	     */
	    menuChar = Tcl_UniCharToUpper(LOWORD(*pwParam));

	    Tcl_DStringInit(&ds);
	    for (i = 0; i < menuPtr->numEntries; i++) {
		underline = menuPtr->entries[i]->underline;
		labelPtr = menuPtr->entries[i]->labelPtr;
		if ((underline != TCL_INDEX_NONE) && (labelPtr != NULL)) {
		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 ((underline + 1 < len + 1) && (menuChar ==
		    if (((TkSizeT)underline + 1 < len + 1) && (menuChar ==
				Tcl_UniCharToUpper(wlabel[underline]))) {
			*plResult = (2 << 16) | i;
			returnResult = 1;
			break;
		    }
		}
	    }
1685
1686
1687
1688
1689
1690
1691
1692

1693
1694
1695
1696
1697
1698
1699
1686
1687
1688
1689
1690
1691
1692

1693
1694
1695
1696
1697
1698
1699
1700







-
+







    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 != MASTER_MENU) {
    if (menuPtr->menuType != MAIN_MENU) {
	*heightPtr = 0;
    } else {
	*heightPtr = fmPtr->linespace;
    }
    *widthPtr = 0;
}

2324
2325
2326
2327
2328
2329
2330
2331

2332
2333
2334
2335
2336
2337

2338
2339
2340
2341
2342
2343
2344
2325
2326
2327
2328
2329
2330
2331

2332
2333
2334
2335
2336
2337

2338
2339
2340
2341
2342
2343
2344
2345







-
+





-
+







    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<Alt_R>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<KeyRelease-Alt_R>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<Alt-KeyPress>", "tk::WinMenuKey %W %N", 0);
	    "<Alt-Key>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<Alt-KeyRelease>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<KeyPress-F10>", "tk::WinMenuKey %W %N", 0);
	    "<Key-F10>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<KeyRelease-F10>", "tk::WinMenuKey %W %N", 0);
}

/*
 *----------------------------------------------------------------------
2593
2594
2595
2596
2597
2598
2599
2600

2601
2602
2603
2604
2605
2606
2607
2594
2595
2596
2597
2598
2599
2600

2601
2602
2603
2604
2605
2606
2607
2608







-
+







    int segmentWidth, maxX;
    Tk_3DBorder border;
    (void)mePtr;
    (void)gc;
    (void)tkfont;
    (void)fmPtr;

    if (menuPtr->menuType != MASTER_MENU) {
    if (menuPtr->menuType != MAIN_MENU) {
	return;
    }

    points[0].x = x;
    points[0].y = y + height/2;
    points[1].y = points[0].y;
    segmentWidth = 6;
3225
3226
3227
3228
3229
3230
3231
3232

3233
3234
3235
3236
3237
3238
3239
3226
3227
3228
3229
3230
3231
3232

3233
3234
3235
3236
3237
3238
3239
3240







-
+







{
    TkMenuReferences *menuRefPtr;
    TkMenu *menuPtr;

    if ((menuName != NULL) && (menuName[0] != '\0')) {
	menuRefPtr = TkFindMenuReferences(interp, menuName);
	if ((menuRefPtr != NULL) && (menuRefPtr->menuPtr != NULL)) {
	    for (menuPtr = menuRefPtr->menuPtr->masterMenuPtr; menuPtr != NULL;
	    for (menuPtr = menuRefPtr->menuPtr->mainMenuPtr; menuPtr != NULL;
		    menuPtr = menuPtr->nextInstancePtr) {
		if (menuPtr->menuType == MENUBAR) {
		    ScheduleMenuReconfigure(menuPtr);
		}
	    }
	}
    }

Changes to win/tkWinPixmap.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






-
+







/*
 * tkWinPixmap.c --
 *
 *	This file contains the Xlib emulation functions pertaining to creating
 *	and destroying pixmaps.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 * Copyright © 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"


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 © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 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"

Changes to win/tkWinPort.h.

91
92
93
94
95
96
97

98
99
100
101
102



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122






123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141







142







+





+
+
+




















+
+
+
+
+
+









-
-
-
-
-
-
-


#define REDO_KEYSYM_LOOKUP

/*
 * See ticket [916c1095438eae56]: GetVersionExW triggers warnings
 */
#if defined(_MSC_VER)
#   pragma warning(disable:4146)
#   pragma warning(disable:4267)
#   pragma warning(disable:4244)
#   pragma warning(disable:4311)
#   pragma warning(disable:4312)
#   pragma warning(disable:4996)
#if !defined(_WIN64)
#   pragma warning(disable:4305)
#endif
#endif

/*
 * The following macro checks to see whether there is buffered
 * input data available for a stdio FILE.
 */

#ifdef _MSC_VER
#    define TK_READ_DATA_PENDING(f) ((f)->_cnt > 0)
#else /* _MSC_VER */
#    define TK_READ_DATA_PENDING(f) ((f)->level > 0)
#endif /* _MSC_VER */

/*
 * The following Tk functions are implemented as macros under Windows.
 */

#define TkpGetPixel(p) (((((p)->red >> 8) & 0xff) \
	| ((p)->green & 0xff00) | (((p)->blue << 8) & 0xff0000)) | 0x20000000)

/*
 * Used by tkWindow.c
 */

#define TkpHandleMapOrUnmap(tkwin, event)  Tk_HandleEvent(event)

/*
 * These calls implement native bitmaps which are not currently
 * supported under Windows.  The macros eliminate the calls.
 */

#define TkpDefineNativeBitmaps()
#define TkpCreateNativeBitmap(display, source) None
#define TkpGetNativeAppBitmap(display, name, w, h) None

/*
 * Other functions not used under Windows
 */

#define TkpWillDrawWidget(tkwin) 1
#define TkpRedrawWidget(tkwin)

#endif /* _WINPORT */

Changes to win/tkWinRegion.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





-
+







/*
 * tkWinRegion.c --
 *
 *	Tk Region emulation code.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 * Copyright © 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"

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 © 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"

Changes to win/tkWinSend.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






-
-
+
+







/*
 * 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) 2003 Pat Thoyts <[email protected]>
 * Copyright © 1997 Sun Microsystems, Inc.
 * Copyright © 2003 Pat Thoyts <[email protected]>
 *
 * 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"

Changes to win/tkWinSendCom.c.

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







-
+







 * We implement a COM class for use in registering Tcl interpreters with the
 * system's Running Object Table. This class implements an IDispatch interface
 * with the following method:
 *	Send(String cmd) As String
 * In other words the Send methods takes a string and evaluates this in the
 * Tcl interpreter. The result is returned as another string.
 *
 * Copyright (C) 2002 Pat Thoyts <[email protected]>
 * Copyright © 2002 Pat Thoyts <[email protected]>
 *
 * 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"
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 *obj,
    TkWinSendCom *comobj,
    VARIANT vCmd,
    VARIANT *pvResult,
    EXCEPINFO *pExcepInfo,
    UINT *puArgErr)
{
    HRESULT hr = S_OK;
    int result = TCL_OK;
    VARIANT v;
    Tcl_Interp *interp = obj->interp;
    Tcl_Interp *interp = comobj->interp;
    Tcl_Obj *scriptPtr;
    Tcl_DString ds;
    (void)puArgErr;

    if (interp == NULL) {
	return S_OK;
    }

Changes to win/tkWinSendCom.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







-
+







/*
 * tkWinSendCom.h --
 *
 *	This file provides procedures that implement the Windows "send"
 *	command, allowing commands to be passed from interpreter to
 *	interpreter.
 *
 * Copyright (C) 2002 Pat Thoyts <[email protected]>
 * Copyright © 2002 Pat Thoyts <[email protected]>
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _tkWinSendCom_h_INCLUDE
#define _tkWinSendCom_h_INCLUDE

Added win/tkWinSysTray.c.





















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
 * tkWinSysTray.c --
 *
 * 	tkWinSysTray.c implements a "systray" Tcl command which permits to
 * 	change the system tray/taskbar icon of a Tk toplevel window and
 * 	a "sysnotify" command to post system notifications.
 *
 * Copyright © 1995-1996 Microsoft Corp.
 * Copyright © 1998 Brueckner & Jarosch Ing.GmbH, Erfurt, Germany
 * Copyright © 2020 Kevin Walzer/WordTech Communications LLC.
 * Copyright © 2020 Eric Boudaillier.
 * Copyright © 2020 Francois Vogel.
 *
 * 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 <windows.h>
#include <shellapi.h>
#include "tkWin.h"
#include "tkWinInt.h"
#include "tkWinIco.h"

/*
 * Based extensively on the winico extension and sample code from Microsoft.
 * Some of the code was adapted into tkWinWM.c to implement the "wm iconphoto"
 * command (TIP 159), and here we are borrowing that code to use Tk images
 * to create system tray icons instead of ico files. Additionally, we are
 * removing obsolete parts of the winico extension, and implementing
 * more of the Shell_Notification API to add balloon/system notifications.
 */

#define GETHINSTANCE Tk_GetHINSTANCE()

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#ifdef HAVE_STDINT_H
#include <stdint.h>
#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

typedef struct IcoInfo {
    HICON hIcon;                /* icon handle returned by LoadIcon. */
    unsigned id;                /* Identifier for command;  used to
                                 * cancel it. */
    Tcl_Obj *taskbar_txt;       /* text to display in the taskbar */
    Tcl_Interp *interp;         /* interp which created the icon */
    Tcl_Obj *taskbar_command;   /* command to eval if events in the taskbar
                                 * arrive */
    int taskbar_flags;          /* taskbar related flags*/
    HWND hwndFocus;
    struct IcoInfo *nextPtr;
} IcoInfo;

/* Per-interp struture */
typedef struct IcoInterpInfo {
    HWND hwnd;                  /* Handler window */
    int counter;                /* Counter for IcoInfo id generation */
    IcoInfo *firstIcoPtr;       /* List of created IcoInfo */
    struct IcoInterpInfo *nextPtr;
} IcoInterpInfo;

#define TASKBAR_ICON 1
#define ICON_MESSAGE WM_USER + 1234

#define HANDLER_CLASS "Wtk_TaskbarHandler"
static HWND CreateTaskbarHandlerWindow(void);

static IcoInterpInfo *firstIcoInterpPtr = NULL;
static Tk_EventProc WinIcoDestroy;

/*
 * If someone wants to see the several masks somewhere on the screen...
 * set the ICO_DRAW define and feel free to make some Tcl commands
 * for accessing it.  The normal drawing of an Icon to a DC is really easy:
 * DrawIcon(hdc,x,y,hIcon) or , more complicated
 * DrawIconEx32PlusMoreParameters ...
 */

/* #define ICO_DRAW */
#ifdef ICO_DRAW
#define RectWidth(r)((r).right - (r).left + 1)
#define RectHeight(r)((r).bottom - (r).top + 1)

/*
 *----------------------------------------------------------------------
 *
 * DrawXORMask --
 *
 * 	Using DIB functions, draw XOR mask on hDC in Rect.
 *
 * Results:
 *	Icon is rendered.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static BOOL
DrawXORMask(
    HDC hDC,
    RECT Rect,
    LPLPICONIMAGE lpIcon)
{
    int x, y;

    /* Sanity checks */
    if (lpIcon == NULL)
        return FALSE;
    if (lpIcon->lpBits == NULL)
        return FALSE;

    /* Account for height*2 thing */
    lpIcon->lpbi->bmiHeader.biHeight /= 2;

    /* Locate it */
    x = Rect.left + ((RectWidth(Rect) - lpIcon->lpbi->bmiHeader.biWidth) / 2);
    y = Rect.top + ((RectHeight(Rect) - lpIcon->lpbi->bmiHeader.biHeight) / 2);

    /* Blast it to the screen */
    SetDIBitsToDevice(hDC, x, y,
            lpIcon->lpbi->bmiHeader.biWidth,
            lpIcon->lpbi->bmiHeader.biHeight,
            0, 0, 0, lpIcon->lpbi->bmiHeader.biHeight,
            lpIcon->lpXOR, lpIcon->lpbi, DIB_RGB_COLORS);

    /* UnAccount for height*2 thing */
    lpIcon->lpbi->bmiHeader.biHeight *= 2;

    return TRUE;
}

/*
 *----------------------------------------------------------------------
 *
 * DrawANDMask --
 *
 * 	Using DIB functions, draw AND mask on hDC in Rect.
 *
 * Results:
 *	Icon is rendered.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

BOOL
DrawANDMask(
    HDC hDC,
    RECT Rect,
    LPLPICONIMAGE lpIcon)
{
    LPBITMAPINFO lpbi;
    int x, y;

    /* Sanity checks */
    if (lpIcon == NULL)
        return FALSE;
    if (lpIcon->lpBits == NULL)
        return FALSE;

    /* Need a bitmap header for the mono mask */
    lpbi = ckalloc(sizeof(BITMAPINFO) + (2 * sizeof(RGBQUAD)));
    lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    lpbi->bmiHeader.biWidth = lpIcon->lpbi->bmiHeader.biWidth;
    lpbi->bmiHeader.biHeight = lpIcon->lpbi->bmiHeader.biHeight / 2;
    lpbi->bmiHeader.biPlanes = 1;
    lpbi->bmiHeader.biBitCount = 1;
    lpbi->bmiHeader.biCompression = BI_RGB;
    lpbi->miHeader.biSizeImage = 0;
    lpbi->bmiHeader.biXPelsPerMeter = 0;
    lpbi->bmiHeader.biYPelsPerMeter = 0;
    lpbi->bmiHeader.biClrUsed = 0;
    lpbi->bmiHeader.biClrImportant = 0;
    lpbi->bmiColors[0].rgbRed = 0;
    lpbi->bmiColors[0].rgbGreen = 0;
    lpbi->bmiColors[0].rgbBlue = 0;
    lpbi->bmiColors[0].rgbReserved = 0;
    lpbi->bmiColors[1].rgbRed = 255;
    lpbi->bmiColors[1].rgbGreen = 255;
    lpbi->bmiColors[1].rgbBlue = 255;
    lpbi->bmiColors[1].rgbReserved = 0;

    /* Locate it */
    x = Rect.left + ((RectWidth(Rect) - lpbi->bmiHeader.biWidth) / 2);
    y = Rect.top + ((RectHeight(Rect) - lpbi->bmiHeader.biHeight) / 2);

    /* Blast it to the screen */
    SetDIBitsToDevice(hDC, x, y,
            lpbi->bmiHeader.biWidth,
            lpbi->bmiHeader.biHeight,
            0, 0, 0, lpbi->bmiHeader.biHeight,
            lpIcon->lpAND, lpbi, DIB_RGB_COLORS);

    /* clean up */
    ckfree((char *) lpbi);

    return TRUE;
}
#endif /* ICO_DRAW */

/*
 *----------------------------------------------------------------------
 *
 * TaskbarOperation --
 *
 * 	Management of icon display.
 *
 * Results:
 *	Icon is displayed or deleted.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TaskbarOperation(
    IcoInterpInfo *icoInterpPtr,
    IcoInfo *icoPtr,
    int oper)
{
    NOTIFYICONDATAW ni;
    WCHAR *str;

    ni.cbSize = sizeof(NOTIFYICONDATAW);
    ni.hWnd = icoInterpPtr->hwnd;
    ni.uID = icoPtr->id;
    ni.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE;
    ni.uCallbackMessage = ICON_MESSAGE;
    ni.hIcon = icoPtr->hIcon;

    if (icoPtr->taskbar_txt != NULL) {
        Tcl_DString dst;
        Tcl_DStringInit(&dst);
        str = (WCHAR *)Tcl_UtfToWCharDString(Tcl_GetString(icoPtr->taskbar_txt), -1, &dst);
        wcsncpy(ni.szTip, str, (Tcl_DStringLength(&dst) + 2) / 2);
        Tcl_DStringFree(&dst);
    } else {
        ni.szTip[0] = 0;
    }

    if (Shell_NotifyIconW(oper, &ni) == 1) {
        if (oper == NIM_ADD || oper == NIM_MODIFY) {
            icoPtr->taskbar_flags |= TASKBAR_ICON;
        }
        if (oper == NIM_DELETE) {
            icoPtr->taskbar_flags &= ~TASKBAR_ICON;
        }
    }
    /* Silently ignore error? */
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * NewIcon --
 *
 * 	Create icon for display in system tray.
 *
 * Results:
 *	Icon is created for display.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static IcoInfo *
NewIcon(
    Tcl_Interp *interp,
    IcoInterpInfo *icoInterpPtr,
    HICON hIcon)
{
    IcoInfo *icoPtr;

    icoPtr = (IcoInfo *)ckalloc(sizeof(IcoInfo));
    memset(icoPtr, 0, sizeof(IcoInfo));
    icoPtr->id = ++icoInterpPtr->counter;
    icoPtr->hIcon = hIcon;
    icoPtr->taskbar_txt = NULL;
    icoPtr->interp = interp;
    icoPtr->taskbar_command = NULL;
    icoPtr->taskbar_flags = 0;
    icoPtr->hwndFocus = NULL;
    icoPtr->nextPtr = icoInterpPtr->firstIcoPtr;
    icoInterpPtr->firstIcoPtr = icoPtr;
    return icoPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeIcoPtr --
 *
 * 	Delete icon and free memory.
 *
 * Results:
 *	Icon is removed from display.
 *
 * Side effects:
 *	Memory/resources freed.
 *
 *----------------------------------------------------------------------
 */

static void
FreeIcoPtr(
    IcoInterpInfo *icoInterpPtr,
    IcoInfo *icoPtr)
{
    IcoInfo *prevPtr;
    if (icoInterpPtr->firstIcoPtr == icoPtr) {
        icoInterpPtr->firstIcoPtr = icoPtr->nextPtr;
    } else {
        for (prevPtr = icoInterpPtr->firstIcoPtr; prevPtr->nextPtr != icoPtr;
                prevPtr = prevPtr->nextPtr) {
            /* Empty loop body. */
        }
        prevPtr->nextPtr = icoPtr->nextPtr;
    }
    if (icoPtr->taskbar_flags & TASKBAR_ICON) {
        TaskbarOperation(icoInterpPtr, icoPtr, NIM_DELETE);
    }
    if (icoPtr->taskbar_txt != NULL) {
        Tcl_DecrRefCount(icoPtr->taskbar_txt);
    }
    if (icoPtr->taskbar_command != NULL) {
        Tcl_DecrRefCount(icoPtr->taskbar_command);
    }
    ckfree(icoPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * GetIcoPtr --
 *
 * 	Get pointer to icon for display.
 *
 * Results:
 *	Icon is obtained for display.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static IcoInfo *
GetIcoPtr(
    Tcl_Interp *interp,
    IcoInterpInfo *icoInterpPtr,
    const char *string)
{
    IcoInfo *icoPtr;
    unsigned id;
    const char *start;
    char *end;

    if (strncmp(string, "ico#", 4) != 0) {
        goto notfound;
    }
    start = string + 4;
    id = strtoul(start, &end, 10);
    if ((end == start) || (*end != 0)) {
        goto notfound;
    }
    for (icoPtr = icoInterpPtr->firstIcoPtr; icoPtr != NULL; icoPtr = icoPtr->nextPtr) {
        if (icoPtr->id == id) {
            return icoPtr;
        }
    }

notfound:
    Tcl_AppendResult(interp, "icon \"", string,
        "\" doesn't exist", (char *) NULL);
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * GetInt --
 *
 * Utility function for calculating buffer length.
 *
 * Results:
 *	Length.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
GetInt(
    long theint,
    char *buffer,
    size_t len)
{
    snprintf(buffer, len, "0x%lx", theint);
    buffer[len - 1] = 0;
    return (int) strlen(buffer);
}

/*
 *----------------------------------------------------------------------
 *
 * GetIntDec --
 *
 * Utility function for calculating buffer length.
 *
 * Results:
 *	Length.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
GetIntDec(
    long theint,
    char *buffer,
    size_t len)
{
    snprintf(buffer, len - 1, "%ld", theint);
    buffer[len - 1] = 0;
    return (int) strlen(buffer);
}

/*
 *----------------------------------------------------------------------
 *
 * TaskbarExpandPercents --
 *
 * Parse strings in taskbar display.
 *
 * Results:
 *	Strings.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static char*
TaskbarExpandPercents(
    IcoInfo *icoPtr,
    const char *msgstring,
    WPARAM wParam,
    LPARAM lParam,
    char *before,
    char *after,
    int *aftersize)
{
#define SPACELEFT (*aftersize-(dst-after)-1)
#define AFTERLEN ((*aftersize>0)?(*aftersize*2):1024)
#define ALLOCLEN ((len>AFTERLEN)?(len*2):AFTERLEN)
    char buffer[TCL_INTEGER_SPACE + 5];
    char* dst;
    dst = after;
    while (*before) {
        const char *ptr = before;
        int len = 1;
        if(*before == '%') {
            switch(before[1]){
                case 'M':
                case 'm': {
                    before++;
                    len = strlen(msgstring);
                    ptr = msgstring;
                    break;
                }
                /* case 'W': {
                   before++;
                   len = (int)strlen(winstring);
                   ptr = winstring;
                   break;
                   }
                */
                case 'i': {
                    before++;
                    snprintf(buffer, sizeof(buffer) - 1, "ico#%d", icoPtr->id);
                    len = strlen(buffer);
                    ptr = buffer;
                    break;
                }
                case 'w': {
                    before++;
                    len = GetInt((long)wParam,buffer, sizeof(buffer));
                    ptr = buffer;
                    break;
                }
                case 'l': {
                    before++;
                    len = GetInt((long)lParam,buffer, sizeof(buffer));
                    ptr = buffer;
                    break;
                }
                case 't': {
                    before++;
                    len = GetInt((long)GetTickCount(), buffer, sizeof(buffer));
                    ptr = buffer;
                    break;
                }
                case 'x': {
                    POINT pt;
                    GetCursorPos(&pt);
                    before++;
                    len = GetIntDec((long)pt.x, buffer, sizeof(buffer));
                    ptr = buffer;
                    break;
                }
                case 'y': {
                    POINT pt;
                    GetCursorPos(&pt);
                    before++;
                    len = GetIntDec((long)pt.y,buffer, sizeof(buffer));
                    ptr = buffer;
                    break;
                }
                case 'X': {
                    DWORD dw;
                    dw = GetMessagePos();
                    before++;
                    len = GetIntDec((long)LOWORD(dw),buffer, sizeof(buffer));
                    ptr = buffer;
                    break;
                }
                case 'Y': {
                    DWORD dw;
                    dw = GetMessagePos();
                    before++;
                    len = GetIntDec((long)HIWORD(dw),buffer, sizeof(buffer));
                    ptr = buffer;
                    break;
                }
                case 'H': {
                    before++;
                    len = GetInt(PTR2INT(icoPtr->hwndFocus), buffer, sizeof(buffer));
                    ptr = buffer;
                    break;
                }
                case '%': {
                    before++;
                    len = 1;
                    ptr = "%";
                    break;
                }
            }
        }
        if (SPACELEFT < len) {
            char *newspace;
            ptrdiff_t dist = dst - after;
            int alloclen = ALLOCLEN;
            newspace = (char *)ckalloc(alloclen);
            if (dist>0)
                memcpy(newspace, after, dist);
            if (after && *aftersize) {
                ckfree(after);
            }
            *aftersize =alloclen;
            after = newspace;
            dst = after + dist;
        }
        if (len > 0) {
            memcpy(dst, ptr, len);
        }
        dst += len;
        if ((dst-after)>(*aftersize-1)) {
            printf("oops\n");
        }
        before++;
    }
    *dst = 0;
    return after;
}

/*
 *----------------------------------------------------------------------
 *
 * TaskbarEval --
 *
 * Parse mouse and keyboard events over taskbar.
 *
 * Results:
 *	Event processing.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
TaskbarEval(
    IcoInfo *icoPtr,
    WPARAM wParam,
    LPARAM lParam)
{
    const char *msgstring = "none";
    char evalspace[200];
    int evalsize = 200;
    char *expanded;
    int fixup = 0;

    switch (lParam) {
    case WM_MOUSEMOVE:
        msgstring = "WM_MOUSEMOVE";
        icoPtr->hwndFocus = GetFocus();
        break;
    case WM_LBUTTONDOWN:
        msgstring = "WM_LBUTTONDOWN";
        fixup = 1;
        break;
    case WM_LBUTTONUP:
        msgstring = "WM_LBUTTONUP";
        fixup = 1;
        break;
    case WM_LBUTTONDBLCLK:
        msgstring = "WM_LBUTTONDBLCLK";
        fixup = 1;
        break;
    case WM_RBUTTONDOWN:
        msgstring = "WM_RBUTTONDOWN";
        fixup = 1;
        break;
    case WM_RBUTTONUP:
        msgstring = "WM_RBUTTONUP";
        fixup = 1;
        break;
    case WM_RBUTTONDBLCLK:
        msgstring = "WM_RBUTTONDBLCLK";
        fixup = 1;
        break;
    case WM_MBUTTONDOWN:
        msgstring = "WM_MBUTTONDOWN";
        fixup = 1;
        break;
    case WM_MBUTTONUP:
        msgstring = "WM_MBUTTONUP";
        fixup = 1;
        break;
    case WM_MBUTTONDBLCLK:
        msgstring = "WM_MBUTTONDBLCLK";
        fixup = 1;
        break;
    default:
        msgstring = "WM_NULL";
        fixup = 0;
    }
    expanded = TaskbarExpandPercents(icoPtr, msgstring, wParam, lParam,
            Tcl_GetString(icoPtr->taskbar_command), evalspace, &evalsize);
    if (icoPtr->interp != NULL) {
        int result;
        HWND hwnd = NULL;

        /* See http://support.microsoft.com/kb/q135788/
         * Seems to have moved to https://www.betaarchive.com/wiki/index.php/Microsoft_KB_Archive/135788 */
        if (fixup) {
            if (icoPtr->hwndFocus != NULL && IsWindow(icoPtr->hwndFocus)) {
                hwnd = icoPtr->hwndFocus;
            } else {
                Tk_Window tkwin = Tk_MainWindow(icoPtr->interp);
                if (tkwin != NULL) {
                    hwnd = Tk_GetHWND(Tk_WindowId(tkwin));
                }
            }
            if (hwnd != NULL) {
                SetForegroundWindow(hwnd);
            }
        }

        result = Tcl_GlobalEval(icoPtr->interp, expanded);

        if (hwnd != NULL) {
            /* See http://support.microsoft.com/kb/q135788/
             * Seems to have moved to https://www.betaarchive.com/wiki/index.php/Microsoft_KB_Archive/135788 */
            PostMessageW(hwnd, WM_NULL, 0, 0);
        }
        if (result != TCL_OK) {
            char buffer[100];
            sprintf(buffer, "\n  (command bound to taskbar-icon ico#%d)", icoPtr->id);
            Tcl_AddErrorInfo(icoPtr->interp, buffer);
            Tcl_BackgroundError(icoPtr->interp);
        }
    }
    if (expanded != evalspace) {
        ckfree(expanded);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TaskbarHandlerProc --
 *
 * 	Windows callback procedure, if ICON_MESSAGE arrives, try to execute
 * 	the taskbar_command.
 *
 * Results:
 *	Command execution.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static LRESULT CALLBACK
TaskbarHandlerProc(
    HWND hwnd,
    UINT message,
    WPARAM wParam,
    LPARAM lParam)
{
    static UINT msgTaskbarCreated = 0;
    IcoInterpInfo *icoInterpPtr;
    IcoInfo *icoPtr;

    switch (message) {
    case WM_CREATE:
        msgTaskbarCreated = RegisterWindowMessage(TEXT("TaskbarCreated"));
        break;

    case ICON_MESSAGE:
        for (icoInterpPtr = firstIcoInterpPtr; icoInterpPtr != NULL; icoInterpPtr = icoInterpPtr->nextPtr) {
            if (icoInterpPtr->hwnd == hwnd) {
                for (icoPtr = icoInterpPtr->firstIcoPtr; icoPtr != NULL; icoPtr = icoPtr->nextPtr) {
                    if (icoPtr->id == wParam) {
                        if (icoPtr->taskbar_command != NULL) {
                            TaskbarEval(icoPtr, wParam, lParam);
                        }
                        break;
                    }
                }
                break;
            }
        }
        break;

    default:
        /*
         * Check to see if explorer has been restarted and we need to
         * re-add our icons.
         */
        if (message == msgTaskbarCreated) {
            for (icoInterpPtr = firstIcoInterpPtr; icoInterpPtr != NULL; icoInterpPtr = icoInterpPtr->nextPtr) {
                if (icoInterpPtr->hwnd == hwnd) {
                    for (icoPtr = icoInterpPtr->firstIcoPtr; icoPtr != NULL; icoPtr = icoPtr->nextPtr) {
                        if (icoPtr->taskbar_flags & TASKBAR_ICON) {
                            TaskbarOperation(icoInterpPtr, icoPtr, NIM_ADD);
                        }
                    }
                    break;
                }
            }
        }
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * RegisterHandlerClass --
 *
 * 	Registers the handler window class.
 *
 * Results:
 *	Handler class registered.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
RegisterHandlerClass(
    HINSTANCE hInstance)
{
    WNDCLASS wndclass;
    memset(&wndclass, 0, sizeof(WNDCLASS));
    wndclass.style = 0;
    wndclass.lpfnWndProc = TaskbarHandlerProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = HANDLER_CLASS;
    return RegisterClass(&wndclass);
}

/*
 *----------------------------------------------------------------------
 *
 * CreateTaskbarHandlerWindow --
 *
 * 	Creates a hidden window to handle taskbar messages.
 *
 * Results:
 *	Hidden window created.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static HWND
CreateTaskbarHandlerWindow(void) {
    static int registered = 0;
    HINSTANCE hInstance = GETHINSTANCE;
    if (!registered) {
        if (!RegisterHandlerClass(hInstance))
            return 0;
        registered = 1;
    }
    return CreateWindow(HANDLER_CLASS, "", WS_OVERLAPPED, 0, 0,
            CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * WinIcoDestroy --
 *
 *	Event handler to delete systray icons when interp main window
 *	is deleted, either by destroy, interp deletion or application
 *	exit.
 *
 * Results:
 *	Icon/window removed and memory freed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
WinIcoDestroy(
    ClientData clientData,
    XEvent *eventPtr)
{
    IcoInterpInfo *icoInterpPtr = (IcoInterpInfo*) clientData;
    IcoInterpInfo *prevIcoInterpPtr;
    IcoInfo *icoPtr;
    IcoInfo *nextPtr;

    if (eventPtr->type != DestroyNotify) {
        return;
    }

    if (firstIcoInterpPtr == icoInterpPtr) {
        firstIcoInterpPtr = icoInterpPtr->nextPtr;
    } else {
        for (prevIcoInterpPtr = firstIcoInterpPtr; prevIcoInterpPtr->nextPtr != icoInterpPtr;
                prevIcoInterpPtr = prevIcoInterpPtr->nextPtr) {
            /* Empty loop body. */
        }
        prevIcoInterpPtr->nextPtr = icoInterpPtr->nextPtr;
    }

    DestroyWindow(icoInterpPtr->hwnd);
    for (icoPtr = icoInterpPtr->firstIcoPtr; icoPtr != NULL; icoPtr = nextPtr) {
            nextPtr = icoPtr->nextPtr;
        FreeIcoPtr(icoInterpPtr, icoPtr);
    }
    ckfree((char *) icoInterpPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * WinSystrayCmd --
 *
 * 	Main command for creating, displaying, and removing icons from taskbar.
 *
 * Results:
 *	Management of icon display in taskbar/system tray.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
WinSystrayCmd(
    ClientData clientData,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    static const char *const cmdStrings[] = {
        "add", "delete", "modify", NULL
    };
    enum { CMD_ADD, CMD_DELETE, CMD_MODIFY };
    static const char *const optStrings[] = {
        "-image", "-text", "-callback", NULL
    };
    enum { OPT_IMAGE, OPT_TEXT, OPT_CALLBACK };
    int cmd, opt;

    HICON hIcon;
    int i;
    IcoInterpInfo *icoInterpPtr = (IcoInterpInfo*) clientData;
    IcoInfo *icoPtr = NULL;

    if (objc < 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "command ...");
        return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], cmdStrings, "command",
            0, &cmd) == TCL_ERROR) {
        return TCL_ERROR;
    }
    switch (cmd) {
        case CMD_ADD:
        case CMD_MODIFY: {
            Tcl_Obj *imageObj = NULL, *textObj = NULL, *callbackObj = NULL;
            int optStart;
            int oper;
            if (cmd == CMD_ADD) {
                optStart = 2;
                oper = NIM_ADD;
            } else {
                optStart = 3;
                oper = NIM_MODIFY;
                if (objc != 5) {
                    Tcl_WrongNumArgs(interp, 2, objv, "id option value");
                    return TCL_ERROR;
                }
                icoPtr = GetIcoPtr(interp, icoInterpPtr, Tcl_GetString(objv[2]));
                if (icoPtr == NULL) {
                    return TCL_ERROR;
                }
            }
            for (i = optStart; i < objc; i += 2) {
                if (Tcl_GetIndexFromObj(interp, objv[i], optStrings, "option",
                        0, &opt) == TCL_ERROR) {
                    return TCL_ERROR;
                }
                if (i+1 >= objc) {
                    Tcl_AppendResult(interp,
                            "missing value for option \"", Tcl_GetString(objv[i]),
                            "\"", NULL);
                    return TCL_ERROR;
                }
                switch (opt) {
                    case OPT_IMAGE:
                        imageObj = objv[i+1];
                        break;
                    case OPT_TEXT:
                        textObj = objv[i+1];
                        break;
                    case OPT_CALLBACK:
                        callbackObj = objv[i+1];
                        break;
                }
            }
            if (cmd == CMD_ADD && imageObj == NULL) {
                Tcl_SetObjResult(interp, Tcl_NewStringObj("missing required option \"-image\"", -1));
                return TCL_ERROR;
            }
            if (imageObj != NULL) {
                Tk_PhotoHandle photo;
                int width, height;
                Tk_PhotoImageBlock block;

                photo = Tk_FindPhoto(interp, Tcl_GetString(imageObj));
                if (photo == NULL) {
                    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
                            "image \"%s\" doesn't exist", Tcl_GetString(imageObj)));
                    return TCL_ERROR;
                }
                Tk_PhotoGetSize(photo, &width, &height);
                Tk_PhotoGetImage(photo, &block);
                hIcon = CreateIcoFromPhoto(width, height, block);
                if (hIcon == NULL) {
                    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
                            "failed to create an iconphoto with image \"%s\"", Tcl_GetString(imageObj)));
                    return TCL_ERROR;
                }
            }
            if (cmd == CMD_ADD) {
                icoPtr = NewIcon(interp, icoInterpPtr, hIcon);
            } else {
                if (imageObj != NULL) {
                    DestroyIcon(icoPtr->hIcon);
                    icoPtr->hIcon = hIcon;
                }
            }
            if (callbackObj != NULL) {
                if (icoPtr->taskbar_command != NULL) {
                    Tcl_DecrRefCount(icoPtr->taskbar_command);
                }
                icoPtr->taskbar_command = callbackObj;
                Tcl_IncrRefCount(icoPtr->taskbar_command);
            }
            if (textObj != NULL) {
                if (icoPtr->taskbar_txt != NULL) {
                    Tcl_DecrRefCount(icoPtr->taskbar_txt);
                }
                icoPtr->taskbar_txt = textObj;
                Tcl_IncrRefCount(icoPtr->taskbar_txt);
            }
            TaskbarOperation(icoInterpPtr, icoPtr, oper);
            if (cmd == CMD_ADD) {
                char buffer[5 + TCL_INTEGER_SPACE];
                int n;
                n = _snprintf(buffer, sizeof(buffer) - 1, "ico#%d", icoPtr->id);
                buffer[n] = 0;
                Tcl_SetObjResult(interp, Tcl_NewStringObj(buffer, n));
            }
            return TCL_OK;
        }
        case CMD_DELETE:
            if (objc != 3) {
                Tcl_WrongNumArgs(interp, 2, objv, "id");
                return TCL_ERROR;
            }
            icoPtr = GetIcoPtr(interp, icoInterpPtr, Tcl_GetString(objv[2]));
            if (icoPtr == NULL) {
                return TCL_ERROR;
            }
            FreeIcoPtr(icoInterpPtr, icoPtr);
            return TCL_OK;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WinSysNotifyCmd --
 *
 * 	Main command for creating and displaying notifications/balloons from system tray.
 *
 * Results:
 *	Display of notifications.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
WinSysNotifyCmd(
    ClientData clientData,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    IcoInterpInfo *icoInterpPtr = (IcoInterpInfo*) clientData;
    IcoInfo *icoPtr;
    Tcl_DString infodst;
    Tcl_DString titledst;
    NOTIFYICONDATAW ni;
    char *msgtitle;
    char *msginfo;

    if (objc < 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "command ...");
        return TCL_ERROR;
    }
    if (strcmp(Tcl_GetString(objv[1]), "notify") != 0) {
        Tcl_AppendResult(interp, "unknown subcommand \"", Tcl_GetString(objv[1]),
                "\": must be notify", NULL);
        return TCL_ERROR;
    }
    if (objc != 5) {
        Tcl_WrongNumArgs(interp, 2, objv, "id title detail");
        return TCL_ERROR;
    }

    icoPtr = GetIcoPtr(interp, icoInterpPtr, Tcl_GetString(objv[2]));
    if (icoPtr == NULL) {
        return TCL_ERROR;
    }

    ni.cbSize = sizeof(NOTIFYICONDATAW);
    ni.hWnd = icoInterpPtr->hwnd;
    ni.uID = icoPtr->id;
    ni.uFlags = NIF_INFO;
    ni.uCallbackMessage = ICON_MESSAGE;
    ni.hIcon = icoPtr->hIcon;
    ni.dwInfoFlags = NIIF_INFO; /* Use a sane platform-specific icon here.*/

    msgtitle = Tcl_GetString(objv[3]);
    msginfo = Tcl_GetString(objv[4]);

    /* Balloon notification for system tray icon. */
    if (msgtitle != NULL) {
        WCHAR *title;
        Tcl_DStringInit(&titledst);
        title = Tcl_UtfToWCharDString(msgtitle, -1, &titledst);
        wcsncpy(ni.szInfoTitle, title, (Tcl_DStringLength(&titledst) + 2) / 2);
        Tcl_DStringFree(&titledst);
    }
    if (msginfo != NULL) {
        WCHAR *info;
        Tcl_DStringInit(&infodst);
        info = Tcl_UtfToWCharDString(msginfo, -1, &infodst);
        wcsncpy(ni.szInfo, info, (Tcl_DStringLength(&infodst) + 2) / 2);
        Tcl_DStringFree(&infodst);
    }

    Shell_NotifyIconW(NIM_MODIFY, &ni);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WinIcoInit --
 *
 * 	Initialize this package and create script-level commands.
 *
 * Results:
 *	Initialization of code.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
WinIcoInit(
    Tcl_Interp *interp)
{
    IcoInterpInfo *icoInterpPtr;
    Tk_Window mainWindow;

#ifdef USE_TCL_STUBS
    if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) {
        return TCL_ERROR;
    }
#endif
#ifdef USE_TK_STUBS
    if (Tk_InitStubs(interp, TK_VERSION, 0) == NULL) {
        return TCL_ERROR;
    }
#endif

    mainWindow = Tk_MainWindow(interp);
    if (mainWindow == NULL) {
        Tcl_SetObjResult(interp, Tcl_NewStringObj("main window has been destroyed", -1));
        return TCL_ERROR;
    }

    icoInterpPtr = (IcoInterpInfo*) ckalloc(sizeof(IcoInterpInfo));
    icoInterpPtr->counter = 0;
    icoInterpPtr->firstIcoPtr = NULL;
    icoInterpPtr->hwnd = CreateTaskbarHandlerWindow();
    icoInterpPtr->nextPtr = firstIcoInterpPtr;
    firstIcoInterpPtr = icoInterpPtr;
    Tcl_CreateObjCommand(interp, "::tk::systray::_systray", WinSystrayCmd,
            (ClientData) icoInterpPtr, NULL);
    Tcl_CreateObjCommand(interp, "::tk::sysnotify::_sysnotify", WinSysNotifyCmd,
            (ClientData) icoInterpPtr, NULL);

    Tk_CreateEventHandler(mainWindow, StructureNotifyMask,
            WinIcoDestroy, (ClientData) icoInterpPtr);

    return TCL_OK;
}

/*
 * Local variables:
 * mode: c
 * indent-tabs-mode: nil
 * End:
 */

Changes to win/tkWinTest.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






-
-
-
+
+
+







/*
 * 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 © 1997 Sun Microsystems, Inc.
 * Copyright © 2000 Scriptics Corporation.
 * Copyright © 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

Changes to win/tkWinWindow.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






-
+







/*
 * tkWinWindow.c --
 *
 *	Xlib emulation routines for Windows related to creating, displaying
 *	and destroying windows.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"
#include "tkBusy.h"

Changes to win/tkWinWm.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








-
-
+
+






+







/*
 * 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 © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 1998-2000 Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"
#include "tkWinIco.h"
#include <shellapi.h>

/*
 * These next two defines are only valid on Win2K/XP+.
 */

#ifndef WS_EX_LAYERED
53
54
55
56
57
58
59
60
61


62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
54
55
56
57
58
59
60


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80




















































81
82
83
84
85
86
87







-
-
+
+


















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-








typedef struct ProtocolHandler {
    Atom protocol;		/* Identifies the protocol. */
    struct ProtocolHandler *nextPtr;
				/* Next in list of protocol handlers for the
				 * same top-level window, or NULL for end of
				 * list. */
    Tcl_Interp *interp;		/* Interpreter in which to invoke command. */
    char command[1];		/* Tcl command to invoke when a client message
    Tcl_Interp *interp;	/* Interpreter in which to invoke command. */
    char command[TKFLEXARRAY];	/* Tcl command to invoke when a client message
				 * for this protocol arrives. The actual size
				 * of the structure varies to accommodate the
				 * needs of the actual command. THIS MUST BE
				 * THE LAST FIELD OF THE STRUCTURE. */
} ProtocolHandler;

#define HANDLER_SIZE(cmdLength) \
    (offsetof(ProtocolHandler, command) + 1 + cmdLength)

/*
 * Helper type passed via lParam to TkWmStackorderToplevelEnumProc
 */

typedef struct TkWmStackorderToplevelPair {
    Tcl_HashTable *table;
    TkWindow **windowPtr;
} TkWmStackorderToplevelPair;

/*
 * This structure represents the contents of a icon, in terms of its image.
 * The HICON is an internal Windows format. Most of these icon-specific
 * structures originated with the Winico extension. We stripped out unused
 * parts of that code, and integrated the code more naturally with Tcl.
 */

typedef struct {
    UINT Width, Height, Colors;	/* Width, Height and bpp */
    LPBYTE lpBits;		/* Ptr to DIB bits */
    DWORD dwNumBytes;		/* How many bytes? */
    LPBITMAPINFO lpbi;		/* Ptr to header */
    LPBYTE lpXOR;		/* Ptr to XOR image bits */
    LPBYTE lpAND;		/* Ptr to AND image bits */
    HICON hIcon;		/* DAS ICON */
} ICONIMAGE, *LPICONIMAGE;

/*
 * This structure is how we represent a block of the above items. We will
 * reallocate these structures according to how many images they need to
 * contain.
 */

typedef struct {
    int nNumImages;		/* How many images? */
    ICONIMAGE IconImages[1];	/* Image entries */
} BlockOfIconImages, *BlockOfIconImagesPtr;

/*
 * These two structures are used to read in icons from an 'icon directory'
 * (i.e. the contents of a .icr file, say). We only use these structures
 * temporarily, since we copy the information we want into a
 * BlockOfIconImages.
 */

typedef struct {
    BYTE bWidth;		/* Width of the image */
    BYTE bHeight;		/* Height of the image (times 2) */
    BYTE bColorCount;		/* Number of colors in image (0 if >=8bpp) */
    BYTE bReserved;		/* Reserved */
    WORD wPlanes;		/* Color Planes */
    WORD wBitCount;		/* Bits per pixel */
    DWORD dwBytesInRes;		/* How many bytes in this resource? */
    DWORD dwImageOffset;	/* Where in the file is this image */
} ICONDIRENTRY, *LPICONDIRENTRY;

typedef struct {
    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.
 * 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:
 *
173
174
175
176
177
178
179
180

181
182
183
184
185
186
187
122
123
124
125
126
127
128

129
130
131
132
133
134
135
136







-
+







    char *iconName;		/* Name to display in icon. Malloced. */
    XWMHints hints;		/* Various pieces of information for window
				 * manager. */
    char *leaderName;		/* Path name of leader of window group
				 * (corresponds to hints.window_group).
				 * Malloc-ed. Note: this field doesn't get
				 * updated if leader is destroyed. */
    TkWindow *masterPtr;	/* Master window for TRANSIENT_FOR property,
    TkWindow *containerPtr;	/* Container window for TRANSIENT_FOR property,
				 * or NULL. */
    Tk_Window icon;		/* Window to use as icon for this window, or
				 * NULL. */
    Tk_Window iconFor;		/* Window for which this window is icon, or
				 * NULL if this isn't an icon for anyone. */

    /*
311
312
313
314
315
316
317
318

319
320
321
322
323
324
325
260
261
262
263
264
265
266

267
268
269
270
271
272
273
274







-
+







 *				allow the user to change the width of the
 *				window (controlled by "wm resizable" command).
 * WM_HEIGHT_NOT_RESIZABLE -	Non-zero means that we're not supposed to
 *				allow the user to change the height of the
 *				window (controlled by "wm resizable" command).
 * WM_WITHDRAWN -		Non-zero means that this window has explicitly
 *				been withdrawn. If it's a transient, it should
 *				not mirror state changes in the master.
 *				not mirror state changes in the container.
 * WM_FULLSCREEN -		Non-zero means that this window has been placed
 *				in the full screen mode. It should be mapped at
 *				0,0 and be the width and height of the screen.
 */

#define WM_NEVER_MAPPED			(1<<0)
#define WM_UPDATE_PENDING		(1<<1)
360
361
362
363
364
365
366
367

368
369
370
371
372
373
374
309
310
311
312
313
314
315

316
317
318
319
320
321
322
323







-
+








static void		TopLevelReqProc(ClientData dummy, Tk_Window tkwin);
static void		RemapWindows(TkWindow *winPtr, HWND parentHWND);

static const Tk_GeomMgr wmMgrType = {
    "wm",			/* name */
    TopLevelReqProc,		/* requestProc */
    NULL,			/* lostSlaveProc */
    NULL,			/* lostContentProc */
};

typedef struct {
    HPALETTE systemPalette;	/* System palette; refers to the currently
				 * installed foreground logical palette. */
    TkWindow *createWindow;	/* Window that is being constructed. This
				 * value is set immediately before a call to
432
433
434
435
436
437
438

439
440
441
442
443
444
445
446
447
448
381
382
383
384
385
386
387
388
389
390

391
392
393
394
395
396
397







+


-







			    WPARAM wParam, LPARAM lParam);
static void		WmWaitVisibilityOrMapProc(ClientData 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);
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
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
489
490
491
492
493
494
495





















































































































































































496
497
498
499
500
501
502







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







static int		WmTransientCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmWithdrawCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		WmUpdateGeom(WmInfo *wmPtr, TkWindow *winPtr);

/*
 * Used in BytesPerLine
 */

#define WIDTHBYTES(bits)	((((bits) + 31)>>5)<<2)

/*
 *----------------------------------------------------------------------
 *
 * DIBNumColors --
 *
 *	Calculates the number of entries in the color table, given by LPSTR
 *	lpbi - pointer to the CF_DIB memory block. Used by titlebar icon code.
 *
 * Results:
 *	WORD - Number of entries in the color table.
 *
 *----------------------------------------------------------------------
 */

static WORD
DIBNumColors(
    LPSTR lpbi)
{
    WORD wBitCount;
    DWORD dwClrUsed;

    dwClrUsed = ((LPBITMAPINFOHEADER) lpbi)->biClrUsed;

    if (dwClrUsed) {
	return (WORD) dwClrUsed;
    }

    wBitCount = ((LPBITMAPINFOHEADER) lpbi)->biBitCount;

    switch (wBitCount) {
    case 1:
	return 2;
    case 4:
	return 16;
    case 8:
	return 256;
    default:
	return 0;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * PaletteSize --
 *
 *	Calculates the number of bytes in the color table, as given by LPSTR
 *	lpbi - pointer to the CF_DIB memory block. Used by titlebar icon code.
 *
 * Results:
 *	Number of bytes in the color table
 *
 *----------------------------------------------------------------------
 */
static WORD
PaletteSize(
    LPSTR lpbi)
{
    return (WORD) (DIBNumColors(lpbi) * sizeof(RGBQUAD));
}

/*
 *----------------------------------------------------------------------
 *
 * FindDIBits --
 *
 *	Locate the image bits in a CF_DIB format DIB, as given by LPSTR lpbi -
 *	pointer to the CF_DIB memory block. Used by titlebar icon code.
 *
 * Results:
 *	pointer to the image bits
 *
 * Side effects: None
 *
 *
 *----------------------------------------------------------------------
 */

static LPSTR
FindDIBBits(
    LPSTR lpbi)
{
    return lpbi + *((LPDWORD) lpbi) + PaletteSize(lpbi);
}

/*
 *----------------------------------------------------------------------
 *
 * BytesPerLine --
 *
 *	Calculates the number of bytes in one scan line, as given by
 *	LPBITMAPINFOHEADER lpBMIH - pointer to the BITMAPINFOHEADER that
 *	begins the CF_DIB block. Used by titlebar icon code.
 *
 * Results:
 *	number of bytes in one scan line (DWORD aligned)
 *
 *----------------------------------------------------------------------
 */

static DWORD
BytesPerLine(
    LPBITMAPINFOHEADER lpBMIH)
{
    return WIDTHBYTES(lpBMIH->biWidth * lpBMIH->biPlanes * lpBMIH->biBitCount);
}

/*
 *----------------------------------------------------------------------
 *
 * AdjustIconImagePointers --
 *
 *	Adjusts internal pointers in icon resource struct, as given by
 *	LPICONIMAGE lpImage - the resource to handle. Used by titlebar icon
 *	code.
 *
 * Results:
 *	BOOL - TRUE for success, FALSE for failure
 *
 *----------------------------------------------------------------------
 */

static BOOL
AdjustIconImagePointers(
    LPICONIMAGE lpImage)
{
    /*
     * Sanity check.
     */

    if (lpImage == NULL) {
	return FALSE;
    }

    /*
     * BITMAPINFO is at beginning of bits.
     */

    lpImage->lpbi = (LPBITMAPINFO) lpImage->lpBits;

    /*
     * Width - simple enough.
     */

    lpImage->Width = lpImage->lpbi->bmiHeader.biWidth;

    /*
     * Icons are stored in funky format where height is doubled so account for
     * that.
     */

    lpImage->Height = (lpImage->lpbi->bmiHeader.biHeight)/2;

    /*
     * How many colors?
     */

    lpImage->Colors = lpImage->lpbi->bmiHeader.biPlanes
	    * lpImage->lpbi->bmiHeader.biBitCount;

    /*
     * XOR bits follow the header and color table.
     */

    lpImage->lpXOR = (LPBYTE) FindDIBBits((LPSTR) lpImage->lpbi);

    /*
     * AND bits follow the XOR bits.
     */

    lpImage->lpAND = lpImage->lpXOR +
	    lpImage->Height*BytesPerLine((LPBITMAPINFOHEADER) lpImage->lpbi);
    return TRUE;
}

/*
 *----------------------------------------------------------------------
 *
 * MakeIconOrCursorFromResource --
 *
 *	Construct an actual HICON structure from the information in a
1294
1295
1296
1297
1298
1299
1300





































































1301
1302
1303
1304
1305
1306
1307
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







	titlebaricon = (WinIconPtr)ckalloc(sizeof(WinIconInstance));
	titlebaricon->iconBlock = lpIR;
	titlebaricon->refCount = 1;
    }
    return titlebaricon;
}


/*
 *----------------------------------------------------------------------
 *
 * AdjustIconImagePointers --
 *
 *	Adjusts internal pointers in icon resource struct, as given by
 *	LPICONIMAGE lpImage - the resource to handle. Used by titlebar icon
 *	code.
 *
 * Results:
 *	BOOL - TRUE for success, FALSE for failure
 *
 *----------------------------------------------------------------------
 */

static BOOL
AdjustIconImagePointers(
    LPICONIMAGE lpImage)
{
    /*
     * Sanity check.
     */

    if (lpImage == NULL) {
	return FALSE;
    }

    /*
     * BITMAPINFO is at beginning of bits.
     */

    lpImage->lpbi = (LPBITMAPINFO) lpImage->lpBits;

    /*
     * Width - simple enough.
     */

    lpImage->Width = lpImage->lpbi->bmiHeader.biWidth;

    /*
     * Icons are stored in funky format where height is doubled so account for
     * that.
     */

    lpImage->Height = (lpImage->lpbi->bmiHeader.biHeight)/2;

    /*
     * How many colors?
     */

    lpImage->Colors = lpImage->lpbi->bmiHeader.biPlanes
	    * lpImage->lpbi->bmiHeader.biBitCount;

    /*
     * XOR bits follow the header and color table.
     */

    lpImage->lpXOR = (LPBYTE) FindDIBBits((LPSTR) lpImage->lpbi);

    /*
     * AND bits follow the XOR bits.
     */

    lpImage->lpAND = lpImage->lpXOR +
	    lpImage->Height*BytesPerLine((LPBITMAPINFOHEADER) lpImage->lpbi);
    return TRUE;
}

/*
 *----------------------------------------------------------------------
 *
 * GetIconFromPixmap --
 *
 *	Turn a Tk Pixmap (i.e. a bitmap) into an icon resource, if possible,
 *	otherwise NULL is returned.
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
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







-
+
















-
+







-
+


-
+







	    Tcl_Panic("UpdateWrapper: Container was destroyed");
	}
    } else {
	/*
	 * Pick the decorative frame style. Override redirect windows get
	 * created as undecorated popups if they have no transient parent,
	 * otherwise they are children. This allows splash screens to operate
	 * as an independent window, while having dropdows (like for a
	 * as an independent window, while having dropdowns (like for a
	 * combobox) not grab focus away from their parent. Transient windows
	 * get a modal dialog frame. Neither override, nor transient windows
	 * appear in the Windows taskbar. Note that a transient window does
	 * not resize by default, so we need to explicitly add the
	 * WS_THICKFRAME style if we want it to be resizeable.
	 */

	if (winPtr->atts.override_redirect) {
	    wmPtr->style = WM_OVERRIDE_STYLE;
	    wmPtr->exStyle = EX_OVERRIDE_STYLE;

	    /*
	     * Parent must be desktop even if we have a transient parent.
	     */

	    parentHWND = GetDesktopWindow();
	    if (wmPtr->masterPtr) {
	    if (wmPtr->containerPtr) {
		wmPtr->style |= WS_CHILD;
	    } else {
		wmPtr->style |= WS_POPUP;
	    }
	} else if (wmPtr->flags & WM_FULLSCREEN) {
	    wmPtr->style = WM_FULLSCREEN_STYLE;
	    wmPtr->exStyle = EX_FULLSCREEN_STYLE;
	} else if (wmPtr->masterPtr) {
	} else if (wmPtr->containerPtr) {
	    wmPtr->style = WM_TRANSIENT_STYLE;
	    wmPtr->exStyle = EX_TRANSIENT_STYLE;
	    parentHWND = Tk_GetHWND(Tk_WindowId(wmPtr->masterPtr));
	    parentHWND = Tk_GetHWND(Tk_WindowId(wmPtr->containerPtr));
	    if (! ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE)
		    && (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE))) {
		wmPtr->style |= WS_THICKFRAME;
	    }
	} else {
	    wmPtr->style = WM_TOPLEVEL_STYLE;
	    wmPtr->exStyle = EX_TOPLEVEL_STYLE;
2200
2201
2202
2203
2204
2205
2206
2207

2208
2209
2210
2211
2212
2213
2214
2215
2216

2217
2218
2219
2220
2221
2222
2223
2037
2038
2039
2040
2041
2042
2043

2044
2045
2046
2047
2048
2049
2050
2051
2052

2053
2054
2055
2056
2057
2058
2059
2060







-
+








-
+







    if (oldWrapper && (oldWrapper != wmPtr->wrapper)
	    && (oldWrapper != GetDesktopWindow())) {
	SetWindowLongPtrW(oldWrapper, GWLP_USERDATA, (LONG_PTR) 0);

	if (wmPtr->numTransients > 0) {
	    /*
	     * Unset the current wrapper as the parent for all transient
	     * children for whom this is the master
	     * children for whom this is the container
	     */

	    WmInfo *wmPtr2;

	    childStateInfo = (int *)ckalloc(wmPtr->numTransients * sizeof(int));
	    state = 0;
	    for (wmPtr2 = winPtr->dispPtr->firstWmPtr; wmPtr2 != NULL;
		    wmPtr2 = wmPtr2->nextPtr) {
		if (wmPtr2->masterPtr == winPtr
		if (wmPtr2->containerPtr == winPtr
			&& !(wmPtr2->flags & WM_NEVER_MAPPED)) {
		    childStateInfo[state++] = wmPtr2->hints.initial_state;
		    SetParent(TkWinGetHWND(wmPtr2->winPtr->window), NULL);
		}
	    }
	}

2288
2289
2290
2291
2292
2293
2294
2295

2296
2297
2298
2299
2300
2301
2302
2303

2304
2305
2306
2307
2308
2309
2310
2125
2126
2127
2128
2129
2130
2131

2132
2133
2134
2135
2136
2137
2138
2139

2140
2141
2142
2143
2144
2145
2146
2147







-
+







-
+







	SetMenu(wmPtr->wrapper, wmPtr->hMenu);
	wmPtr->flags &= ~WM_SYNC_PENDING;
    }

    if (childStateInfo) {
	if (wmPtr->numTransients > 0) {
	    /*
	     * Reset all transient children for whom this is the master.
	     * Reset all transient children for whom this is the container.
	     */

	    WmInfo *wmPtr2;

	    state = 0;
	    for (wmPtr2 = winPtr->dispPtr->firstWmPtr; wmPtr2 != NULL;
		    wmPtr2 = wmPtr2->nextPtr) {
		if (wmPtr2->masterPtr == winPtr
		if (wmPtr2->containerPtr == winPtr
			&& !(wmPtr2->flags & WM_NEVER_MAPPED)) {
		    UpdateWrapper(wmPtr2->winPtr);
		    TkpWmSetState(wmPtr2->winPtr, childStateInfo[state++]);
		}
	    }
	}

2361
2362
2363
2364
2365
2366
2367
2368

2369
2370
2371

2372
2373
2374
2375
2376
2377
2378
2198
2199
2200
2201
2202
2203
2204

2205
2206
2207

2208
2209
2210
2211
2212
2213
2214
2215







-
+


-
+








    if (!tsdPtr->initialized) {
	InitWm();
    }

    if (wmPtr->flags & WM_NEVER_MAPPED) {
	/*
	 * Don't map a transient if the master is not mapped.
	 * Don't map a transient if the container is not mapped.
	 */

	if (wmPtr->masterPtr != NULL && !Tk_IsMapped(wmPtr->masterPtr)) {
	if (wmPtr->containerPtr != NULL && !Tk_IsMapped(wmPtr->containerPtr)) {
	    wmPtr->hints.initial_state = WithdrawnState;
	    return;
	}
    } else {
	if (wmPtr->hints.initial_state == WithdrawnState) {
	    return;
	}
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
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







-
+




-
+

-
+


-
+







		prevPtr->nextPtr = wmPtr->nextPtr;
		break;
	    }
	}
    }

    /*
     * Reset all transient windows whose master is the dead window.
     * Reset all transient windows whose container is the dead window.
     */

    for (wmPtr2 = winPtr->dispPtr->firstWmPtr; wmPtr2 != NULL;
	 wmPtr2 = wmPtr2->nextPtr) {
	if (wmPtr2->masterPtr == winPtr) {
	if (wmPtr2->containerPtr == winPtr) {
	    wmPtr->numTransients--;
	    Tk_DeleteEventHandler((Tk_Window) wmPtr2->masterPtr,
	    Tk_DeleteEventHandler((Tk_Window) wmPtr2->containerPtr,
		    VisibilityChangeMask|StructureNotifyMask,
		    WmWaitVisibilityOrMapProc, wmPtr2->winPtr);
	    wmPtr2->masterPtr = NULL;
	    wmPtr2->containerPtr = NULL;
	    if ((wmPtr2->wrapper != NULL)
		    && !(wmPtr2->flags & (WM_NEVER_MAPPED))) {
		UpdateWrapper(wmPtr2->winPtr);
	    }
	}
    }
    if (wmPtr->numTransients != 0)
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
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







-
-
+
+


-
+





-
+


-
+







    }
    if (wmPtr->clientMachine != NULL) {
	ckfree(wmPtr->clientMachine);
    }
    if (wmPtr->flags & WM_UPDATE_PENDING) {
	Tcl_CancelIdleCall(UpdateGeometryInfo, winPtr);
    }
    if (wmPtr->masterPtr != NULL) {
	wmPtr2 = wmPtr->masterPtr->wmInfoPtr;
    if (wmPtr->containerPtr != NULL) {
	wmPtr2 = wmPtr->containerPtr->wmInfoPtr;

	/*
	 * If we had a master, tell them that we aren't tied to them anymore.
	 * If we had a container, tell them that we aren't tied to them anymore.
	 */

	if (wmPtr2 != NULL) {
	    wmPtr2->numTransients--;
	}
	Tk_DeleteEventHandler((Tk_Window) wmPtr->masterPtr,
	Tk_DeleteEventHandler((Tk_Window) wmPtr->containerPtr,
		VisibilityChangeMask|StructureNotifyMask,
		WmWaitVisibilityOrMapProc, winPtr);
	wmPtr->masterPtr = NULL;
	wmPtr->containerPtr = NULL;
    }
    if (wmPtr->crefObj != NULL) {
	Tcl_DecrRefCount(wmPtr->crefObj);
	wmPtr->crefObj = NULL;
    }

    /*
2805
2806
2807
2808
2809
2810
2811
2812

2813
2814
2815
2816
2817
2818
2819
2642
2643
2644
2645
2646
2647
2648

2649
2650
2651
2652
2653
2654
2655
2656







-
+








    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;
3070
3071
3072
3073
3074
3075
3076
3077

3078
3079
3080
3081
3082
3083
3084
2907
2908
2909
2910
2911
2912
2913

2914
2915
2916
2917
2918
2919
2920
2921







-
+







		Tcl_NewStringObj("-topmost", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewWideIntObj((exStyle & WS_EX_TOPMOST) != 0));
	Tcl_SetObjResult(interp, objPtr);
	return TCL_OK;
    }
    for (i = 3; i < objc; i += 2) {
	string = TkGetStringFromObj(objv[i], &length);
	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)
3138
3139
3140
3141
3142
3143
3144
3145

3146
3147
3148
3149
3150
3151
3152
2975
2976
2977
2978
2979
2980
2981

2982
2983
2984
2985
2986
2987
2988
2989







-
+







		    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);
		    const char *crefstr = Tcl_GetStringFromObj(objv[i+1], &length);

		    if (length == 0) {
			/* reset to no transparent color */
			if (wmPtr->crefObj) {
			    Tcl_DecrRefCount(wmPtr->crefObj);
			    wmPtr->crefObj = NULL;
			}
3331
3332
3333
3334
3335
3336
3337
3338

3339
3340
3341
3342
3343
3344
3345
3168
3169
3170
3171
3172
3173
3174

3175
3176
3177
3178
3179
3180
3181
3182







-
+







    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"));
3404
3405
3406
3407
3408
3409
3410
3411

3412
3413
3414
3415
3416
3417
3418
3241
3242
3243
3244
3245
3246
3247

3248
3249
3250
3251
3252
3253
3254
3255







-
+







	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,
		    TkNewWindowObj((Tk_Window) wmPtr->cmapList[i]));
		    Tk_NewWindowObj((Tk_Window) wmPtr->cmapList[i]));
	}
	Tcl_SetObjResult(interp, resultObj);
	return TCL_OK;
    }
    if (Tcl_ListObjGetElements(interp, objv[3], &windowObjc, &windowObjv)
	    != TCL_OK) {
	return TCL_ERROR;
3941
3942
3943
3944
3945
3946
3947
3948

3949
3950
3951
3952
3953
3954
3955
3778
3779
3780
3781
3782
3783
3784

3785
3786
3787
3788
3789
3790
3791
3792







-
+







    }
    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 {
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
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







-
+













-
+








-
+







    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(
		"can't iconify \"%s\": override-redirect flag is set",
		winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "OVERRIDE_REDIRECT",
		NULL);
	return TCL_ERROR;
    }
    if (wmPtr->masterPtr != NULL) {
    if (wmPtr->containerPtr != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't iconify \"%s\": it is a transient",
		winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "TRANSIENT", NULL);
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't iconify %s: it is an icon for %s",
		"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;
}
4268
4269
4270
4271
4272
4273
4274
4275

4276
4277
4278
4279
4280
4281
4282
4105
4106
4107
4108
4109
4110
4111

4112
4113
4114
4115
4116
4117
4118
4119







-
+







	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;
4306
4307
4308
4309
4310
4311
4312
4313

4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4143
4144
4145
4146
4147
4148
4149

4150


4151
4152
4153
4154


4155
4156
4157
4158
4159
4160
4161







-
+
-
-




-
-







    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, width, height, idx, bufferSize, startObj = 3;
    int i, width, height, 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;
    }
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
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







-
-





-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-

-
-
-
-
-
+

-
+








+







    size = sizeof(BlockOfIconImages) + (sizeof(ICONIMAGE) * (objc-startObj-1));
    lpIR = (BlockOfIconImagesPtr)attemptckalloc(size);
    if (lpIR == NULL) {
	return TCL_ERROR;
    }
    ZeroMemory(lpIR, size);

    lpIR->nNumImages = objc - startObj;

    for (i = startObj; i < objc; i++) {
	photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i]));
	Tk_PhotoGetSize(photo, &width, &height);
	Tk_PhotoGetImage(photo, &block);

	/*
	 * Don't use CreateIcon to create the icon, as it requires color
	 * bitmap data in device-dependent format. Instead we use
	 * CreateIconIndirect which takes device-independent bitmaps and
	 * converts them as required. Initialise icon info structure.
	 */

	ZeroMemory(&iconInfo, sizeof(iconInfo));
	iconInfo.fIcon = TRUE;

	/*
	 * Create device-independent color bitmap.
	 */

	ZeroMemory(&bmInfo, sizeof bmInfo);
	bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmInfo.bmiHeader.biWidth = width;
	bmInfo.bmiHeader.biHeight = -height;
	bmInfo.bmiHeader.biPlanes = 1;
	bmInfo.bmiHeader.biBitCount = 32;
	bmInfo.bmiHeader.biCompression = BI_RGB;

	iconInfo.hbmColor = CreateDIBSection(NULL, &bmInfo, DIB_RGB_COLORS,
		&bgraPixel.voidPtr, NULL, 0);
	if (!iconInfo.hbmColor) {
	    ckfree(lpIR);
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "failed to create an iconphoto with image \"%s\"",
		    Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "IMAGE", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Convert the photo image data into BGRA format (RGBQUAD).
	 */

	bufferSize = height * width * 4;
	for (idx = 0 ; idx < bufferSize ; idx += 4) {
	    bgraPixel.ptr[idx] = block.pixelPtr[idx+2];
	    bgraPixel.ptr[idx+1] = block.pixelPtr[idx+1];
	    bgraPixel.ptr[idx+2] = block.pixelPtr[idx+0];
	    bgraPixel.ptr[idx+3] = block.pixelPtr[idx+3];
	}

	/*
	 * Create a dummy mask bitmap. The contents of this don't appear to
	 * matter, as CreateIconIndirect will setup the icon mask based on the
	 * alpha channel in our color bitmap.
	 */

	bmInfo.bmiHeader.biBitCount = 1;

	iconInfo.hbmMask = CreateDIBSection(NULL, &bmInfo, DIB_RGB_COLORS,
		&bgraMask.voidPtr, NULL, 0);
	if (!iconInfo.hbmMask) {
	    DeleteObject(iconInfo.hbmColor);
	    ckfree(lpIR);
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "failed to create mask bitmap for \"%s\"",
		    Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "MASK", NULL);
	    return TCL_ERROR;
	}

	ZeroMemory(bgraMask.ptr, width*height/8);

	/*
	 * Create an icon from the bitmaps.
	 */

	hIcon = CreateIconIndirect(&iconInfo);
	hIcon = CreateIcoFromPhoto(width, height, block);
	DeleteObject(iconInfo.hbmColor);
	DeleteObject(iconInfo.hbmMask);
	if (hIcon == NULL) {
	    /*
	     * XXX should free up created icons.
	     */

	    ckfree(lpIR);
	    FreeIconBlock(lpIR);
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "failed to create icon for \"%s\"",
		    "failed to create an iconphoto with image \"%s\"",
		    Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "ICON", NULL);
	    return TCL_ERROR;
	}
	lpIR->IconImages[i-startObj].Width = width;
	lpIR->IconImages[i-startObj].Height = height;
	lpIR->IconImages[i-startObj].Colors = 4;
	lpIR->IconImages[i-startObj].hIcon = hIcon;
	lpIR->nNumImages++;
    }

    titlebaricon = (WinIconPtr)ckalloc(sizeof(WinIconInstance));
    titlebaricon->iconBlock = lpIR;
    titlebaricon->refCount = 1;
    if (WinSetIcon(interp, titlebaricon, (Tk_Window) useWinPtr) != TCL_OK) {
	/*
4565
4566
4567
4568
4569
4570
4571
4572

4573
4574
4575
4576
4577
4578
4579
4320
4321
4322
4323
4324
4325
4326

4327
4328
4329
4330
4331
4332
4333
4334







-
+








    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, TkNewWindowObj(wmPtr->icon));
	    Tcl_SetObjResult(interp, Tk_NewWindowObj(wmPtr->icon));
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->hints.flags &= ~IconWindowHint;
	if (wmPtr->icon != NULL) {
	    /*
5027
5028
5029
5030
5031
5032
5033
5034

5035
5036
5037
5038
5039
5040
5041
4782
4783
4784
4785
4786
4787
4788

4789
4790
4791
4792
4793
4794
4795
4796







-
+







	    } 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);
5218
5219
5220
5221
5222
5223
5224
5225

5226
5227
5228
5229
5230
5231
5232
4973
4974
4975
4976
4977
4978
4979

4980
4981
4982
4983
4984
4985
4986
4987







-
+








    if (objc == 3) {
	windows = TkWmStackorderToplevel(winPtr);
	if (windows != NULL) {
	    resultObj = Tcl_NewObj();
	    for (windowPtr = windows; *windowPtr ; windowPtr++) {
		Tcl_ListObjAppendElement(NULL, resultObj,
			TkNewWindowObj((Tk_Window) *windowPtr));
			Tk_NewWindowObj((Tk_Window) *windowPtr));
	    }
	    Tcl_SetObjResult(interp, resultObj);
	    ckfree(windows);
	    return TCL_OK;
	} else {
	    return TCL_ERROR;
	}
5399
5400
5401
5402
5403
5404
5405
5406

5407
5408
5409
5410
5411
5412
5413
5154
5155
5156
5157
5158
5159
5160

5161
5162
5163
5164
5165
5166
5167
5168







-
+







		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't iconify \"%s\": override-redirect flag is set",
			winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "STATE",
			"OVERRIDE_REDIRECT", NULL);
		return TCL_ERROR;
	    }
	    if (wmPtr->masterPtr != NULL) {
	    if (wmPtr->containerPtr != NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't iconify \"%s\": it is a transient",
			winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "STATE", "TRANSIENT",
			NULL);
		return TCL_ERROR;
	    }
5503
5504
5505
5506
5507
5508
5509
5510

5511
5512
5513
5514
5515
5516
5517
5258
5259
5260
5261
5262
5263
5264

5265
5266
5267
5268
5269
5270
5271
5272







-
+







	    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);
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
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







-
+



-
+



-
-
+
+




-
+

-
+



-
-
+
+




-
+


-
+


-
+

-
+


-
+

-
+









-
+



-
+




-
-
+
+


-
-
+
+




-
+

-
-
-
+
+
+


-
-
-
+
+
+




-
-
+
+



-
+




-
-
+
+







    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    TkWindow *masterPtr = wmPtr->masterPtr, **masterPtrPtr = &masterPtr, *w;
    TkWindow *containerPtr = wmPtr->containerPtr, **containerPtrPtr = &containerPtr, *w;
    WmInfo *wmPtr2;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?master?");
	Tcl_WrongNumArgs(interp, 2, objv, "window ?window?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (masterPtr != NULL) {
	    Tcl_SetObjResult(interp, TkNewWindowObj((Tk_Window) masterPtr));
	if (containerPtr != NULL) {
	    Tcl_SetObjResult(interp, Tk_NewWindowObj((Tk_Window) containerPtr));
	}
	return TCL_OK;
    }
    if (Tcl_GetString(objv[3])[0] == '\0') {
	if (masterPtr != NULL) {
	if (containerPtr != NULL) {
	    /*
	     * If we had a master, tell them that we aren't tied to them
	     * If we had a container, tell them that we aren't tied to them
	     * anymore.
	     */

	    masterPtr->wmInfoPtr->numTransients--;
	    Tk_DeleteEventHandler((Tk_Window) masterPtr,
	    containerPtr->wmInfoPtr->numTransients--;
	    Tk_DeleteEventHandler((Tk_Window) containerPtr,
		    VisibilityChangeMask|StructureNotifyMask,
		    WmWaitVisibilityOrMapProc, winPtr);
	}

	wmPtr->masterPtr = NULL;
	wmPtr->containerPtr = NULL;
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3],
		(Tk_Window *) masterPtrPtr) != TCL_OK) {
		(Tk_Window *) containerPtrPtr) != TCL_OK) {
	    return TCL_ERROR;
	}
	while (!Tk_TopWinHierarchy(masterPtr)) {
	while (!Tk_TopWinHierarchy(containerPtr)) {
	    /*
	     * Ensure that the master window is actually a Tk toplevel.
	     * Ensure that the container window is actually a Tk toplevel.
	     */

	    masterPtr = masterPtr->parentPtr;
	    containerPtr = containerPtr->parentPtr;
	}
	Tk_MakeWindowExist((Tk_Window) masterPtr);
	Tk_MakeWindowExist((Tk_Window) containerPtr);

	if (wmPtr->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't make \"%s\" a transient: it is an icon for %s",
		    Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
	    return TCL_ERROR;
	}

	wmPtr2 = masterPtr->wmInfoPtr;
	wmPtr2 = containerPtr->wmInfoPtr;

	if (wmPtr2->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't make \"%s\" a master: it is an icon for %s",
		    "can't make \"%s\" a container: it is an icon for %s",
		    Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
	    return TCL_ERROR;
	}
	for (w = masterPtr; w != NULL && w->wmInfoPtr != NULL;
	     w = (TkWindow *)w->wmInfoPtr->masterPtr) {
	for (w = containerPtr; w != NULL && w->wmInfoPtr != NULL;
	     w = (TkWindow *)w->wmInfoPtr->containerPtr) {
	    if (w == winPtr) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "setting \"%s\" as master creates a transient/master cycle",
		    Tk_PathName(masterPtr)));
		    "can't set \"%s\" as container: would cause management loop",
		    Tk_PathName(containerPtr)));
		Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
		return TCL_ERROR;
	    }
	}
	if (masterPtr != wmPtr->masterPtr) {
	if (containerPtr != wmPtr->containerPtr) {
	    /*
	     * Remove old master map/unmap binding before setting the new
	     * master. The event handler will ensure that transient states
	     * reflect the state of the master.
	     * Remove old container map/unmap binding before setting the new
	     * container. The event handler will ensure that transient states
	     * reflect the state of the container.
	     */

	    if (wmPtr->masterPtr != NULL) {
		wmPtr->masterPtr->wmInfoPtr->numTransients--;
		Tk_DeleteEventHandler((Tk_Window) wmPtr->masterPtr,
	    if (wmPtr->containerPtr != NULL) {
		wmPtr->containerPtr->wmInfoPtr->numTransients--;
		Tk_DeleteEventHandler((Tk_Window) wmPtr->containerPtr,
			VisibilityChangeMask|StructureNotifyMask,
			WmWaitVisibilityOrMapProc, winPtr);
	    }

	    masterPtr->wmInfoPtr->numTransients++;
	    Tk_CreateEventHandler((Tk_Window) masterPtr,
	    containerPtr->wmInfoPtr->numTransients++;
	    Tk_CreateEventHandler((Tk_Window) containerPtr,
		    VisibilityChangeMask|StructureNotifyMask,
		    WmWaitVisibilityOrMapProc, winPtr);

	    wmPtr->masterPtr = masterPtr;
	    wmPtr->containerPtr = containerPtr;
	}
    }
    if (!((wmPtr->flags & WM_NEVER_MAPPED)
	    && !(winPtr->flags & TK_EMBEDDED))) {
	if (wmPtr->masterPtr != NULL
		&& !Tk_IsMapped(wmPtr->masterPtr)) {
	if (wmPtr->containerPtr != NULL
		&& !Tk_IsMapped(wmPtr->containerPtr)) {
	    TkpWmSetState(winPtr, WithdrawnState);
	} else {
	    UpdateWrapper(winPtr);
	}
    }
    return TCL_OK;
}
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
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







-
+

-
+











-
+








static void
WmWaitVisibilityOrMapProc(
    ClientData clientData,	/* Pointer to window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkWindow *winPtr = (TkWindow *)clientData;
    TkWindow *masterPtr = winPtr->wmInfoPtr->masterPtr;
    TkWindow *containerPtr = winPtr->wmInfoPtr->containerPtr;

    if (masterPtr == NULL)
    if (containerPtr == NULL)
	return;

    if (eventPtr->type == MapNotify) {
	if (!(winPtr->wmInfoPtr->flags & WM_WITHDRAWN)) {
	    TkpWmSetState(winPtr, NormalState);
	}
    } else if (eventPtr->type == UnmapNotify) {
	TkpWmSetState(winPtr, WithdrawnState);
    }

    if (eventPtr->type == VisibilityNotify) {
	int state = masterPtr->wmInfoPtr->hints.initial_state;
	int state = containerPtr->wmInfoPtr->hints.initial_state;

	if ((state == NormalState) || (state == ZoomState)) {
	    state = winPtr->wmInfoPtr->hints.initial_state;
	    if ((state == NormalState) || (state == ZoomState)) {
		UpdateWrapper(winPtr);
	    }
	}

Changes to win/tkWinX.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





-
-
-
+
+
+







/*
 * 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 © 1995-1996 Sun Microsystems, Inc.
 * Copyright © 1994 Software Research Associates, Inc.
 * Copyright © 1998-2000 Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"

124
125
126
127
128
129
130
131
132
133
134
135
136

137
138
139
140
141
142
143
144
124
125
126
127
128
129
130






131

132
133
134
135
136
137
138







-
-
-
-
-
-
+
-







				 * display and server. */
{
    static char buffer[32]; /* Empty string means not initialized yet. */
    OSVERSIONINFOW os;
    (void)tkwin;

    if (!buffer[0]) {
	HMODULE handle = GetModuleHandleW(L"NTDLL");
	int(__stdcall *getversion)(void *) = (int(__stdcall *)(void *))
		(void *)GetProcAddress(handle, "RtlGetVersion");
	os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
	if (!getversion || getversion(&os)) {
	    GetVersionExW(&os);
	GetVersionExW(&os);
	}
	/* Write the first character last, preventing multi-thread issues. */
	sprintf(buffer+1, "indows %d.%d %d %s", (int)os.dwMajorVersion,
		(int)os.dwMinorVersion, (int)os.dwBuildNumber,
#ifdef _WIN64
		"Win64"
#else
		"Win32"
345
346
347
348
349
350
351
352

353
354
355
356
357

358
359
360
361
362
363
364
365
366

367
368
369
370
371
372
373
339
340
341
342
343
344
345

346
347
348
349
350

351
352
353
354
355
356
357
358
359

360
361
362
363
364
365
366
367







-
+




-
+








-
+







	}

	/*
	 * Set tkWinTheme to be TK_THEME_WIN_(CLASSIC|XP|VISTA). The
	 * TK_THEME_WIN_CLASSIC could be set even when running under XP if the
	 * windows classic theme was selected.
	 */
	if ((os.dwMajorVersion == 5) && (os.dwMinorVersion == 1)) {
	if (os.dwMajorVersion == 5 && os.dwMinorVersion >= 1) {
	    HKEY hKey;
	    LPCWSTR szSubKey = L"Control Panel\\Appearance";
	    LPCWSTR szCurrent = L"Current";
	    DWORD dwSize = 200;
	    char pBuffer[200];
	    WCHAR pBuffer[200];

	    memset(pBuffer, 0, dwSize);
	    if (RegOpenKeyExW(HKEY_CURRENT_USER, szSubKey, 0L,
		    KEY_READ, &hKey) != ERROR_SUCCESS) {
		tkWinTheme = TK_THEME_WIN_XP;
	    } else {
		RegQueryValueExW(hKey, szCurrent, NULL, NULL, (LPBYTE) pBuffer, &dwSize);
		RegCloseKey(hKey);
		if (strcmp(pBuffer, "Windows Standard") == 0) {
		if (wcscmp(pBuffer, L"Windows Standard") == 0) {
		    tkWinTheme = TK_THEME_WIN_CLASSIC;
		} else {
		    tkWinTheme = TK_THEME_WIN_XP;
		}
	    }
	} else if (os.dwMajorVersion > 5) {
	    tkWinTheme = TK_THEME_WIN_VISTA;
1742
1743
1744
1745
1746
1747
1748
1749

1750
1751
1752
1753

1754
1755
1756
1757
1758
1759
1760
1736
1737
1738
1739
1740
1741
1742

1743
1744
1745
1746

1747
1748
1749
1750
1751
1752
1753
1754







-
+



-
+







	msg = WM_MBUTTONDOWN;
	wparam = MK_MBUTTON;
	break;
    case Button3:
	msg = WM_RBUTTONDOWN;
	wparam = MK_RBUTTON;
	break;
    case Button4:
    case Button8:
	msg = WM_XBUTTONDOWN;
	wparam = MAKEWPARAM(MK_XBUTTON1, XBUTTON1);
	break;
    case Button5:
    case Button9:
	msg = WM_XBUTTONDOWN;
	wparam = MAKEWPARAM(MK_XBUTTON2, XBUTTON2);
	break;
    default:
	return 0;
    }

Changes to win/ttkWinTheme.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
-
+








-
+







/* winTheme.c - Copyright (C) 2004 Pat Thoyts <[email protected]>
/* winTheme.c - Copyright © 2004 Pat Thoyts <[email protected]>
 */

#ifdef _MSC_VER
#define WIN32_LEAN_AND_MEAN
#endif

#include <tkWinInt.h>

#ifndef DFCS_HOT	/* Windows 98/Me, Windows 200/XP only */
#ifndef DFCS_HOT	/* Windows 98/Me, Windows 2000/XP only */
#define DFCS_HOT 0
#endif

#include "ttk/ttkTheme.h"

/*
 * BoxToRect --
742
743
744
745
746
747
748
749
750


751
752
753
754
755
756
757
742
743
744
745
746
747
748


749
750
751
752
753
754
755
756
757







-
-
+
+







    TTK_GROUP("Button.border", TTK_FILL_BOTH,
	TTK_GROUP("Button.padding", TTK_FILL_BOTH,
	    TTK_NODE("Button.label", TTK_FILL_BOTH))))

TTK_LAYOUT("TCombobox",
    TTK_GROUP("Combobox.field", TTK_FILL_BOTH,
	TTK_NODE("Combobox.downarrow", TTK_PACK_RIGHT|TTK_FILL_Y)
	TTK_GROUP("Combobox.padding", TTK_PACK_LEFT|TTK_EXPAND|TTK_FILL_BOTH,
	    TTK_GROUP("Combobox.focus", TTK_PACK_LEFT|TTK_EXPAND|TTK_FILL_BOTH,
	TTK_GROUP("Combobox.padding", TTK_FILL_BOTH,
	    TTK_GROUP("Combobox.focus", TTK_FILL_BOTH,
		TTK_NODE("Combobox.textarea", TTK_FILL_BOTH)))))

TTK_END_LAYOUT_TABLE

/* ---------------------------------------------------------------------- */

MODULE_SCOPE

Changes to win/ttkWinXPTheme.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




-
-
-
+
+
+







/*
 * Tk theme engine which uses the Windows XP "Visual Styles" API
 * Adapted from Georgios Petasis' XP theme patch.
 *
 * Copyright (c) 2003 by Georgios Petasis, [email protected].
 * Copyright (c) 2003 by Joe English
 * Copyright (c) 2003 by Pat Thoyts
 * Copyright © 2003 Georgios Petasis, [email protected].
 * Copyright © 2003 Joe English
 * Copyright © 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/
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







-
+







    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    GenericElementSize,
    TreeIndicatorElementDraw
};

#if BROKEN_TEXT_ELEMENT
#ifdef BROKEN_TEXT_ELEMENT

/*
 *----------------------------------------------------------------------
 * Text element (does not work yet).
 *
 * According to "Using Windows XP Visual Styles",  we need to select
 * a font into the DC before calling DrawThemeText().
834
835
836
837
838
839
840
841

842
843
844
845
846
847
848
849
850

851
852
853
854
855
856
857
834
835
836
837
838
839
840

841
842
843
844
845
846
847
848
849

850
851
852
853
854
855
856
857







-
+








-
+







    const char *src;
    TkSizeT 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;
    }
873
874
875
876
877
878
879
880

881
882
883
884
885
886
887
888
889

890
891
892
893
894
895
896
873
874
875
876
877
878
879

880
881
882
883
884
885
886
887
888

889
890
891
892
893
894
895
896







-
+








-
+







    const char *src;
    TkSizeT 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);
}

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
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







-
-
+
+

















-
-
+
+




-
-
+
+







    TTK_GROUP("Button.button", TTK_FILL_BOTH,
	TTK_GROUP("Button.focus", TTK_FILL_BOTH,
	    TTK_GROUP("Button.padding", TTK_FILL_BOTH,
		TTK_NODE("Button.label", TTK_FILL_BOTH)))))

TTK_LAYOUT("TMenubutton",
    TTK_NODE("Menubutton.dropdown", TTK_PACK_RIGHT|TTK_FILL_Y)
    TTK_GROUP("Menubutton.button", TTK_PACK_RIGHT|TTK_EXPAND|TTK_FILL_BOTH,
	    TTK_GROUP("Menubutton.padding", TTK_PACK_LEFT|TTK_EXPAND|TTK_FILL_X,
    TTK_GROUP("Menubutton.button", TTK_FILL_BOTH,
	    TTK_GROUP("Menubutton.padding", TTK_FILL_X,
	        TTK_NODE("Menubutton.label", 0))))

TTK_LAYOUT("Horizontal.TScrollbar",
    TTK_GROUP("Horizontal.Scrollbar.trough", TTK_FILL_X,
	TTK_NODE("Horizontal.Scrollbar.leftarrow", TTK_PACK_LEFT)
	TTK_NODE("Horizontal.Scrollbar.rightarrow", TTK_PACK_RIGHT)
	TTK_GROUP("Horizontal.Scrollbar.thumb", TTK_FILL_BOTH|TTK_UNIT,
	    TTK_NODE("Horizontal.Scrollbar.grip", 0))))

TTK_LAYOUT("Vertical.TScrollbar",
    TTK_GROUP("Vertical.Scrollbar.trough", TTK_FILL_Y,
	TTK_NODE("Vertical.Scrollbar.uparrow", TTK_PACK_TOP)
	TTK_NODE("Vertical.Scrollbar.downarrow", TTK_PACK_BOTTOM)
	TTK_GROUP("Vertical.Scrollbar.thumb", TTK_FILL_BOTH|TTK_UNIT,
	    TTK_NODE("Vertical.Scrollbar.grip", 0))))

TTK_LAYOUT("Horizontal.TScale",
    TTK_GROUP("Scale.focus", TTK_EXPAND|TTK_FILL_BOTH,
	TTK_GROUP("Horizontal.Scale.trough", TTK_EXPAND|TTK_FILL_BOTH,
    TTK_GROUP("Scale.focus", TTK_FILL_BOTH,
	TTK_GROUP("Horizontal.Scale.trough", TTK_FILL_BOTH,
	    TTK_NODE("Horizontal.Scale.track", TTK_FILL_X)
	    TTK_NODE("Horizontal.Scale.slider", TTK_PACK_LEFT) )))

TTK_LAYOUT("Vertical.TScale",
    TTK_GROUP("Scale.focus", TTK_EXPAND|TTK_FILL_BOTH,
	TTK_GROUP("Vertical.Scale.trough", TTK_EXPAND|TTK_FILL_BOTH,
    TTK_GROUP("Scale.focus", TTK_FILL_BOTH,
	TTK_GROUP("Vertical.Scale.trough", TTK_FILL_BOTH,
	    TTK_NODE("Vertical.Scale.track", TTK_FILL_Y)
	    TTK_NODE("Vertical.Scale.slider", TTK_PACK_TOP) )))

TTK_END_LAYOUT_TABLE

/*----------------------------------------------------------------------
 * +++ XP element info table:
1042
1043
1044
1045
1046
1047
1048
1049
1050

1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1042
1043
1044
1045
1046
1047
1048


1049
1050
1051
1052

1053
1054
1055
1056
1057
1058
1059







-
-
+



-







	EP_EDITTEXT, edittext_statemap, PAD(1, 1, 1, 1), 0 },
    { "Spinbox.uparrow", &SpinboxArrowElementSpec, L"SPIN",
	SPNP_UP, spinbutton_statemap, NOPAD,
	PAD_MARGINS | ((SM_CXVSCROLL << 8) | SM_CYVSCROLL) },
    { "Spinbox.downarrow", &SpinboxArrowElementSpec, L"SPIN",
	SPNP_DOWN, spinbutton_statemap, NOPAD,
	PAD_MARGINS | ((SM_CXVSCROLL << 8) | SM_CYVSCROLL) },

#if BROKEN_TEXT_ELEMENT
#ifdef BROKEN_TEXT_ELEMENT
    { "Labelframe.text", &TextElementSpec, L"BUTTON",
    	BP_GROUPBOX, groupbox_statemap, NOPAD,0 },
#endif

    { 0,0,0,0,0,NOPAD,0 }
};
#undef PAD


static int
GetSysFlagFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *resultPtr)
1140
1141
1142
1143
1144
1145
1146
1147

1148
1149
1150
1151
1152
1153
1154
1138
1139
1140
1141
1142
1143
1144

1145
1146
1147
1148
1149
1150
1151
1152







-
+







	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;
	for (i = 3; i < objc; i += 2) {

Changes to win/winMain.c.

9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35









36
37
38
39
40
41
42



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62



63


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79


80
81
82
83
84
85
86
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32




33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101







+
















-
-
-
-
+
+
+
+
+
+
+
+
+







+
+
+




















+
+
+
-
+
+
















+
+







 * Copyright (c) 1998-1999 Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tk.h"
#include "tkWinInt.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#include <locale.h>
#include <stdlib.h>
#include <tchar.h>

#if defined(__GNUC__)
int _CRT_glob = 0;
#endif /* __GNUC__ */

#ifdef TK_TEST
#ifdef __cplusplus
extern "C" {
#endif
extern Tcl_PackageInitProc Tktest_Init;
#ifdef __cplusplus
}
#endif
#endif /* TK_TEST */
#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;
#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()
 */

#ifdef TK_LOCAL_MAIN_HOOK
MODULE_SCOPE int TK_LOCAL_MAIN_HOOK(int *argc, TCHAR ***argv);
#endif

/* Make sure the stubbed variants of those are never used. */
#undef Tcl_ObjSetVar2
#undef Tcl_NewStringObj



/*
 *----------------------------------------------------------------------
 *
 * _tWinMain --
 *
 *	Main entry point from Windows.
205
206
207
208
209
210
211
212

213
214
215
216
217

218
219
220
221
222
223
224
220
221
222
223
224
225
226

227
228
229
230
231

232
233
234
235
236
237
238
239







-
+




-
+







	    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);
    Tcl_StaticPackage(interp, "Registry", Registry_Init, 0);

    if (Dde_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "dde", Dde_Init, Dde_SafeInit);
    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);
246
247
248
249
250
251
252

253
254
255
256
257
258
259
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275







+







     * run interactively. Typically the startup file is "~/.apprc" where "app"
     * is the name of the application. If this line is deleted then no user-
     * specific startup file will be run under any conditions.
     */

    Tcl_ObjSetVar2(interp, Tcl_NewStringObj("tcl_rcFileName", -1), NULL,
	    Tcl_NewStringObj("~/wishrc.tcl", -1), TCL_GLOBAL_ONLY);

    return TCL_OK;
}

#if defined(TK_TEST)
/*
 *----------------------------------------------------------------------
 *
274
275
276
277
278
279
280

281
282
283
284
285
286
287
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304







+







#ifdef TCL_BROKEN_MAINARGS
int
main(
    int argc,
    char **dummy)
{
    TCHAR **argv;
    (void)dummy;
#else
int
_tmain(
    int argc,
    TCHAR **argv)
{
#endif

Changes to win/wish.exe.manifest.in.

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
24
25
26
27
28
29
30


31
32
33
34
35
36
37







-
-







	    <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
	    <!-- Windows 8.1 -->
	    <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
	    <!-- Windows 8 -->
	    <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
	    <!-- Windows 7 -->
	    <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
	    <!-- Windows Vista -->
	    <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
	</application>
    </compatibility>
    <asmv3:application>
	<asmv3:windowsSettings
		xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
	    <dpiAware>true</dpiAware>
	</asmv3:windowsSettings>

Changes to xlib/X11/Xlib.h.

378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
378
379
380
381
382
383
384



385
386
387
388
389
390
391







-
-
-







    int depth;			/* depth of image */
    int bytes_per_line;		/* accelarator to next line */
    int bits_per_pixel;		/* bits per pixel (ZPixmap) */
    unsigned long red_mask;	/* bits in z arrangment */
    unsigned long green_mask;
    unsigned long blue_mask;
    XPointer obdata;		/* hook for the object routines to hang on */
#if defined(MAC_OSX_TK)
    int pixelpower;		/* n such that pixels are 2^n x 2^n blocks*/
#endif
    struct funcs {		/* image manipulation routines */
	struct _XImage *(*create_image)(
		struct _XDisplay* /* display */,
		Visual*		/* visual */,
		unsigned int	/* depth */,
		int		/* format */,
		int		/* offset */,

Changes to xlib/X11/keysymdef.h.

82
83
84
85
86
87
88
89
90


91
92
93
94
95
96
97
82
83
84
85
86
87
88


89
90
91
92
93
94
95
96
97







-
-
+
+







 *
 * Where several mnemonic names are defined for the same keysym in this
 * file, all but the first one listed should be considered deprecated.
 *
 * Mnemonic names for keysyms are defined in this file with lines
 * that match one of these Perl regular expressions:
 *
 *    /^\#define XK_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*\/\* U+([0-9A-F]{4,6}) (.*) \*\/\s*$/
 *    /^\#define XK_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*\/\*\(U+([0-9A-F]{4,6}) (.*)\)\*\/\s*$/
 *    /^\#define XK_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*\/\* 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,
177
178
179
180
181
182
183


184
185
186
187
188


189
190
191
192
193
194
195
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199







+
+





+
+







#define XK_Prior                         0xff55  /* Prior, previous */
#define XK_Page_Up                       0xff55
#define XK_Next                          0xff56  /* Next */
#define XK_Page_Down                     0xff56
#define XK_End                           0xff57  /* EOL */
#define XK_Begin                         0xff58  /* BOL */


#ifndef TK_NO_DEPRECATED
/* Special Windows keyboard keys */

#define XK_Win_L		0xFF5B	/* Left-hand Windows */
#define XK_Win_R		0xFF5C	/* Right-hand Windows */
#define XK_App			0xFF5D	/* Menu key */
#endif


/* Misc functions */

#define XK_Select                        0xff60  /* Select, mark */
#define XK_Print                         0xff61
#define XK_Execute                       0xff62  /* Execute, run, do */
#define XK_Insert                        0xff63  /* Insert, insert here */
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
886
887
888
889
890
891
892
































893
894
895
896
897
898
899







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







#define XK_omacron                       0x03f2  /* U+014D LATIN SMALL LETTER O WITH MACRON */
#define XK_kcedilla                      0x03f3  /* U+0137 LATIN SMALL LETTER K WITH CEDILLA */
#define XK_uogonek                       0x03f9  /* U+0173 LATIN SMALL LETTER U WITH OGONEK */
#define XK_utilde                        0x03fd  /* U+0169 LATIN SMALL LETTER U WITH TILDE */
#define XK_umacron                       0x03fe  /* U+016B LATIN SMALL LETTER U WITH MACRON */
#endif /* XK_LATIN4 */

/*
 * Latin 8
 */
#ifdef XK_LATIN8
#define XK_Wcircumflex                0x1000174  /* U+0174 LATIN CAPITAL LETTER W WITH CIRCUMFLEX */
#define XK_wcircumflex                0x1000175  /* U+0175 LATIN SMALL LETTER W WITH CIRCUMFLEX */
#define XK_Ycircumflex                0x1000176  /* U+0176 LATIN CAPITAL LETTER Y WITH CIRCUMFLEX */
#define XK_ycircumflex                0x1000177  /* U+0177 LATIN SMALL LETTER Y WITH CIRCUMFLEX */
#define XK_Babovedot                  0x1001e02  /* U+1E02 LATIN CAPITAL LETTER B WITH DOT ABOVE */
#define XK_babovedot                  0x1001e03  /* U+1E03 LATIN SMALL LETTER B WITH DOT ABOVE */
#define XK_Dabovedot                  0x1001e0a  /* U+1E0A LATIN CAPITAL LETTER D WITH DOT ABOVE */
#define XK_dabovedot                  0x1001e0b  /* U+1E0B LATIN SMALL LETTER D WITH DOT ABOVE */
#define XK_Fabovedot                  0x1001e1e  /* U+1E1E LATIN CAPITAL LETTER F WITH DOT ABOVE */
#define XK_fabovedot                  0x1001e1f  /* U+1E1F LATIN SMALL LETTER F WITH DOT ABOVE */
#define XK_Mabovedot                  0x1001e40  /* U+1E40 LATIN CAPITAL LETTER M WITH DOT ABOVE */
#define XK_mabovedot                  0x1001e41  /* U+1E41 LATIN SMALL LETTER M WITH DOT ABOVE */
#define XK_Pabovedot                  0x1001e56  /* U+1E56 LATIN CAPITAL LETTER P WITH DOT ABOVE */
#define XK_pabovedot                  0x1001e57  /* U+1E57 LATIN SMALL LETTER P WITH DOT ABOVE */
#define XK_Sabovedot                  0x1001e60  /* U+1E60 LATIN CAPITAL LETTER S WITH DOT ABOVE */
#define XK_sabovedot                  0x1001e61  /* U+1E61 LATIN SMALL LETTER S WITH DOT ABOVE */
#define XK_Tabovedot                  0x1001e6a  /* U+1E6A LATIN CAPITAL LETTER T WITH DOT ABOVE */
#define XK_tabovedot                  0x1001e6b  /* U+1E6B LATIN SMALL LETTER T WITH DOT ABOVE */
#define XK_Wgrave                     0x1001e80  /* U+1E80 LATIN CAPITAL LETTER W WITH GRAVE */
#define XK_wgrave                     0x1001e81  /* U+1E81 LATIN SMALL LETTER W WITH GRAVE */
#define XK_Wacute                     0x1001e82  /* U+1E82 LATIN CAPITAL LETTER W WITH ACUTE */
#define XK_wacute                     0x1001e83  /* U+1E83 LATIN SMALL LETTER W WITH ACUTE */
#define XK_Wdiaeresis                 0x1001e84  /* U+1E84 LATIN CAPITAL LETTER W WITH DIAERESIS */
#define XK_wdiaeresis                 0x1001e85  /* U+1E85 LATIN SMALL LETTER W WITH DIAERESIS */
#define XK_Ygrave                     0x1001ef2  /* U+1EF2 LATIN CAPITAL LETTER Y WITH GRAVE */
#define XK_ygrave                     0x1001ef3  /* U+1EF3 LATIN SMALL LETTER Y WITH GRAVE */
#endif /* XK_LATIN8 */

/*
 * Latin 9
 * Byte 3 = 0x13
 */

#ifdef XK_LATIN9
#define XK_OE                            0x13bc  /* U+0152 LATIN CAPITAL LIGATURE OE */
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
981
982
983
984
985
986
987

















988











989
990
991
992
993
994
995







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-








/*
 * Arabic
 * Byte 3 = 5
 */

#ifdef XK_ARABIC
#define XK_Farsi_0                    0x10006f0  /* U+06F0 EXTENDED ARABIC-INDIC DIGIT ZERO */
#define XK_Farsi_1                    0x10006f1  /* U+06F1 EXTENDED ARABIC-INDIC DIGIT ONE */
#define XK_Farsi_2                    0x10006f2  /* U+06F2 EXTENDED ARABIC-INDIC DIGIT TWO */
#define XK_Farsi_3                    0x10006f3  /* U+06F3 EXTENDED ARABIC-INDIC DIGIT THREE */
#define XK_Farsi_4                    0x10006f4  /* U+06F4 EXTENDED ARABIC-INDIC DIGIT FOUR */
#define XK_Farsi_5                    0x10006f5  /* U+06F5 EXTENDED ARABIC-INDIC DIGIT FIVE */
#define XK_Farsi_6                    0x10006f6  /* U+06F6 EXTENDED ARABIC-INDIC DIGIT SIX */
#define XK_Farsi_7                    0x10006f7  /* U+06F7 EXTENDED ARABIC-INDIC DIGIT SEVEN */
#define XK_Farsi_8                    0x10006f8  /* U+06F8 EXTENDED ARABIC-INDIC DIGIT EIGHT */
#define XK_Farsi_9                    0x10006f9  /* U+06F9 EXTENDED ARABIC-INDIC DIGIT NINE */
#define XK_Arabic_percent             0x100066a  /* U+066A ARABIC PERCENT SIGN */
#define XK_Arabic_superscript_alef    0x1000670  /* U+0670 ARABIC LETTER SUPERSCRIPT ALEF */
#define XK_Arabic_tteh                0x1000679  /* U+0679 ARABIC LETTER TTEH */
#define XK_Arabic_peh                 0x100067e  /* U+067E ARABIC LETTER PEH */
#define XK_Arabic_tcheh               0x1000686  /* U+0686 ARABIC LETTER TCHEH */
#define XK_Arabic_ddal                0x1000688  /* U+0688 ARABIC LETTER DDAL */
#define XK_Arabic_rreh                0x1000691  /* U+0691 ARABIC LETTER RREH */
#define XK_Arabic_comma                  0x05ac  /* U+060C ARABIC COMMA */
#define XK_Arabic_fullstop            0x10006d4  /* U+06D4 ARABIC FULL STOP */
#define XK_Arabic_0                   0x1000660  /* U+0660 ARABIC-INDIC DIGIT ZERO */
#define XK_Arabic_1                   0x1000661  /* U+0661 ARABIC-INDIC DIGIT ONE */
#define XK_Arabic_2                   0x1000662  /* U+0662 ARABIC-INDIC DIGIT TWO */
#define XK_Arabic_3                   0x1000663  /* U+0663 ARABIC-INDIC DIGIT THREE */
#define XK_Arabic_4                   0x1000664  /* U+0664 ARABIC-INDIC DIGIT FOUR */
#define XK_Arabic_5                   0x1000665  /* U+0665 ARABIC-INDIC DIGIT FIVE */
#define XK_Arabic_6                   0x1000666  /* U+0666 ARABIC-INDIC DIGIT SIX */
#define XK_Arabic_7                   0x1000667  /* U+0667 ARABIC-INDIC DIGIT SEVEN */
#define XK_Arabic_8                   0x1000668  /* U+0668 ARABIC-INDIC DIGIT EIGHT */
#define XK_Arabic_9                   0x1000669  /* U+0669 ARABIC-INDIC DIGIT NINE */
#define XK_Arabic_semicolon              0x05bb  /* U+061B ARABIC SEMICOLON */
#define XK_Arabic_question_mark          0x05bf  /* U+061F ARABIC QUESTION MARK */
#define XK_Arabic_hamza                  0x05c1  /* U+0621 ARABIC LETTER HAMZA */
#define XK_Arabic_maddaonalef            0x05c2  /* U+0622 ARABIC LETTER ALEF WITH MADDA ABOVE */
#define XK_Arabic_hamzaonalef            0x05c3  /* U+0623 ARABIC LETTER ALEF WITH HAMZA ABOVE */
#define XK_Arabic_hamzaonwaw             0x05c4  /* U+0624 ARABIC LETTER WAW WITH HAMZA ABOVE */
#define XK_Arabic_hamzaunderalef         0x05c5  /* U+0625 ARABIC LETTER ALEF WITH HAMZA BELOW */
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
1030
1031
1032
1033
1034
1035
1036













1037
1038
1039
1040
1041
1042
1043
1044
































1045
1046
1047
1048
1049
1050
1051







-
-
-
-
-
-
-
-
-
-
-
-
-








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







#define XK_Arabic_dammatan               0x05ec  /* U+064C ARABIC DAMMATAN */
#define XK_Arabic_kasratan               0x05ed  /* U+064D ARABIC KASRATAN */
#define XK_Arabic_fatha                  0x05ee  /* U+064E ARABIC FATHA */
#define XK_Arabic_damma                  0x05ef  /* U+064F ARABIC DAMMA */
#define XK_Arabic_kasra                  0x05f0  /* U+0650 ARABIC KASRA */
#define XK_Arabic_shadda                 0x05f1  /* U+0651 ARABIC SHADDA */
#define XK_Arabic_sukun                  0x05f2  /* U+0652 ARABIC SUKUN */
#define XK_Arabic_madda_above         0x1000653  /* U+0653 ARABIC MADDAH ABOVE */
#define XK_Arabic_hamza_above         0x1000654  /* U+0654 ARABIC HAMZA ABOVE */
#define XK_Arabic_hamza_below         0x1000655  /* U+0655 ARABIC HAMZA BELOW */
#define XK_Arabic_jeh                 0x1000698  /* U+0698 ARABIC LETTER JEH */
#define XK_Arabic_veh                 0x10006a4  /* U+06A4 ARABIC LETTER VEH */
#define XK_Arabic_keheh               0x10006a9  /* U+06A9 ARABIC LETTER KEHEH */
#define XK_Arabic_gaf                 0x10006af  /* U+06AF ARABIC LETTER GAF */
#define XK_Arabic_noon_ghunna         0x10006ba  /* U+06BA ARABIC LETTER NOON GHUNNA */
#define XK_Arabic_heh_doachashmee     0x10006be  /* U+06BE ARABIC LETTER HEH DOACHASHMEE */
#define XK_Farsi_yeh                  0x10006cc  /* U+06CC ARABIC LETTER FARSI YEH */
#define XK_Arabic_farsi_yeh           0x10006cc  /* U+06CC ARABIC LETTER FARSI YEH */
#define XK_Arabic_yeh_baree           0x10006d2  /* U+06D2 ARABIC LETTER YEH BARREE */
#define XK_Arabic_heh_goal            0x10006c1  /* U+06C1 ARABIC LETTER HEH GOAL */
#define XK_Arabic_switch                 0xff7e  /* Alias for mode_switch */
#endif /* XK_ARABIC */

/*
 * Cyrillic
 * Byte 3 = 6
 */
#ifdef XK_CYRILLIC
#define XK_Cyrillic_GHE_bar           0x1000492  /* U+0492 CYRILLIC CAPITAL LETTER GHE WITH STROKE */
#define XK_Cyrillic_ghe_bar           0x1000493  /* U+0493 CYRILLIC SMALL LETTER GHE WITH STROKE */
#define XK_Cyrillic_ZHE_descender     0x1000496  /* U+0496 CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER */
#define XK_Cyrillic_zhe_descender     0x1000497  /* U+0497 CYRILLIC SMALL LETTER ZHE WITH DESCENDER */
#define XK_Cyrillic_KA_descender      0x100049a  /* U+049A CYRILLIC CAPITAL LETTER KA WITH DESCENDER */
#define XK_Cyrillic_ka_descender      0x100049b  /* U+049B CYRILLIC SMALL LETTER KA WITH DESCENDER */
#define XK_Cyrillic_KA_vertstroke     0x100049c  /* U+049C CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE */
#define XK_Cyrillic_ka_vertstroke     0x100049d  /* U+049D CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE */
#define XK_Cyrillic_EN_descender      0x10004a2  /* U+04A2 CYRILLIC CAPITAL LETTER EN WITH DESCENDER */
#define XK_Cyrillic_en_descender      0x10004a3  /* U+04A3 CYRILLIC SMALL LETTER EN WITH DESCENDER */
#define XK_Cyrillic_U_straight        0x10004ae  /* U+04AE CYRILLIC CAPITAL LETTER STRAIGHT U */
#define XK_Cyrillic_u_straight        0x10004af  /* U+04AF CYRILLIC SMALL LETTER STRAIGHT U */
#define XK_Cyrillic_U_straight_bar    0x10004b0  /* U+04B0 CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE */
#define XK_Cyrillic_u_straight_bar    0x10004b1  /* U+04B1 CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE */
#define XK_Cyrillic_HA_descender      0x10004b2  /* U+04B2 CYRILLIC CAPITAL LETTER HA WITH DESCENDER */
#define XK_Cyrillic_ha_descender      0x10004b3  /* U+04B3 CYRILLIC SMALL LETTER HA WITH DESCENDER */
#define XK_Cyrillic_CHE_descender     0x10004b6  /* U+04B6 CYRILLIC CAPITAL LETTER CHE WITH DESCENDER */
#define XK_Cyrillic_che_descender     0x10004b7  /* U+04B7 CYRILLIC SMALL LETTER CHE WITH DESCENDER */
#define XK_Cyrillic_CHE_vertstroke    0x10004b8  /* U+04B8 CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE */
#define XK_Cyrillic_che_vertstroke    0x10004b9  /* U+04B9 CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE */
#define XK_Cyrillic_SHHA              0x10004ba  /* U+04BA CYRILLIC CAPITAL LETTER SHHA */
#define XK_Cyrillic_shha              0x10004bb  /* U+04BB CYRILLIC SMALL LETTER SHHA */

#define XK_Cyrillic_SCHWA             0x10004d8  /* U+04D8 CYRILLIC CAPITAL LETTER SCHWA */
#define XK_Cyrillic_schwa             0x10004d9  /* U+04D9 CYRILLIC SMALL LETTER SCHWA */
#define XK_Cyrillic_I_macron          0x10004e2  /* U+04E2 CYRILLIC CAPITAL LETTER I WITH MACRON */
#define XK_Cyrillic_i_macron          0x10004e3  /* U+04E3 CYRILLIC SMALL LETTER I WITH MACRON */
#define XK_Cyrillic_O_bar             0x10004e8  /* U+04E8 CYRILLIC CAPITAL LETTER BARRED O */
#define XK_Cyrillic_o_bar             0x10004e9  /* U+04E9 CYRILLIC SMALL LETTER BARRED O */
#define XK_Cyrillic_U_macron          0x10004ee  /* U+04EE CYRILLIC CAPITAL LETTER U WITH MACRON */
#define XK_Cyrillic_u_macron          0x10004ef  /* U+04EF CYRILLIC SMALL LETTER U WITH MACRON */

#define XK_Serbian_dje                   0x06a1  /* U+0452 CYRILLIC SMALL LETTER DJE */
#define XK_Macedonia_gje                 0x06a2  /* U+0453 CYRILLIC SMALL LETTER GJE */
#define XK_Cyrillic_io                   0x06a3  /* U+0451 CYRILLIC SMALL LETTER IO */
#define XK_Ukrainian_ie                  0x06a4  /* U+0454 CYRILLIC SMALL LETTER UKRAINIAN IE */
#define XK_Ukranian_je                   0x06a4  /* deprecated */
#define XK_Macedonia_dse                 0x06a5  /* U+0455 CYRILLIC SMALL LETTER DZE */
#define XK_Ukrainian_i                   0x06a6  /* U+0456 CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */
1456
1457
1458
1459
1460
1461
1462
1463

1464
1465

1466
1467
1468
1469
1470
1471
1472
1355
1356
1357
1358
1359
1360
1361

1362
1363

1364
1365
1366
1367
1368
1369
1370
1371







-
+

-
+







#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)*/
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
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







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


-
-
-
-
-
-
-
+
+
+
+
+
+
+


-
-
+
+


-
-
-
+
+
+






-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-



-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-











-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







#define XK_Hangul_SingleCandidate        0xff3c  /* Single candidate */
#define XK_Hangul_MultipleCandidate      0xff3d  /* Multiple candidate */
#define XK_Hangul_PreviousCandidate      0xff3e  /* Previous candidate */
#define XK_Hangul_Special                0xff3f  /* Special symbols */
#define XK_Hangul_switch                 0xff7e  /* Alias for mode_switch */

/* Hangul Consonant Characters */
#define XK_Hangul_Kiyeog                 0x0ea1
#define XK_Hangul_SsangKiyeog            0x0ea2
#define XK_Hangul_KiyeogSios             0x0ea3
#define XK_Hangul_Nieun                  0x0ea4
#define XK_Hangul_NieunJieuj             0x0ea5
#define XK_Hangul_NieunHieuh             0x0ea6
#define XK_Hangul_Dikeud                 0x0ea7
#define XK_Hangul_SsangDikeud            0x0ea8
#define XK_Hangul_Rieul                  0x0ea9
#define XK_Hangul_RieulKiyeog            0x0eaa
#define XK_Hangul_RieulMieum             0x0eab
#define XK_Hangul_RieulPieub             0x0eac
#define XK_Hangul_RieulSios              0x0ead
#define XK_Hangul_RieulTieut             0x0eae
#define XK_Hangul_RieulPhieuf            0x0eaf
#define XK_Hangul_RieulHieuh             0x0eb0
#define XK_Hangul_Mieum                  0x0eb1
#define XK_Hangul_Pieub                  0x0eb2
#define XK_Hangul_SsangPieub             0x0eb3
#define XK_Hangul_PieubSios              0x0eb4
#define XK_Hangul_Sios                   0x0eb5
#define XK_Hangul_SsangSios              0x0eb6
#define XK_Hangul_Ieung                  0x0eb7
#define XK_Hangul_Jieuj                  0x0eb8
#define XK_Hangul_SsangJieuj             0x0eb9
#define XK_Hangul_Cieuc                  0x0eba
#define XK_Hangul_Khieuq                 0x0ebb
#define XK_Hangul_Tieut                  0x0ebc
#define XK_Hangul_Phieuf                 0x0ebd
#define XK_Hangul_Hieuh                  0x0ebe
#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_separation_mark   0x100055d  /* U+055D ARMENIAN COMMA */
#define XK_Armenian_but               0x100055d  /* U+055D ARMENIAN COMMA */
#define XK_Armenian_hyphen            0x100058a  /* U+058A ARMENIAN HYPHEN */
#define XK_Armenian_yentamna          0x100058a  /* U+058A ARMENIAN HYPHEN */
#define XK_Armenian_exclam            0x100055c  /* U+055C ARMENIAN EXCLAMATION MARK */
#define XK_Armenian_amanak            0x100055c  /* U+055C ARMENIAN EXCLAMATION MARK */
#define XK_Armenian_accent            0x100055b  /* U+055B ARMENIAN EMPHASIS MARK */
#define XK_Armenian_shesht            0x100055b  /* U+055B ARMENIAN EMPHASIS MARK */
#define XK_Armenian_question          0x100055e  /* U+055E ARMENIAN QUESTION MARK */
#define XK_Armenian_paruyk            0x100055e  /* U+055E ARMENIAN QUESTION MARK */
#define XK_Armenian_AYB               0x1000531  /* U+0531 ARMENIAN CAPITAL LETTER AYB */
#define XK_Armenian_ayb               0x1000561  /* U+0561 ARMENIAN SMALL LETTER AYB */
#define XK_Armenian_BEN               0x1000532  /* U+0532 ARMENIAN CAPITAL LETTER BEN */
#define XK_Armenian_ben               0x1000562  /* U+0562 ARMENIAN SMALL LETTER BEN */
#define XK_Armenian_GIM               0x1000533  /* U+0533 ARMENIAN CAPITAL LETTER GIM */
#define XK_Armenian_gim               0x1000563  /* U+0563 ARMENIAN SMALL LETTER GIM */
#define XK_Armenian_DA                0x1000534  /* U+0534 ARMENIAN CAPITAL LETTER DA */
#define XK_Armenian_da                0x1000564  /* U+0564 ARMENIAN SMALL LETTER DA */
#define XK_Armenian_YECH              0x1000535  /* U+0535 ARMENIAN CAPITAL LETTER ECH */
#define XK_Armenian_yech              0x1000565  /* U+0565 ARMENIAN SMALL LETTER ECH */
#define XK_Armenian_ZA                0x1000536  /* U+0536 ARMENIAN CAPITAL LETTER ZA */
#define XK_Armenian_za                0x1000566  /* U+0566 ARMENIAN SMALL LETTER ZA */
#define XK_Armenian_E                 0x1000537  /* U+0537 ARMENIAN CAPITAL LETTER EH */
#define XK_Armenian_e                 0x1000567  /* U+0567 ARMENIAN SMALL LETTER EH */
#define XK_Armenian_AT                0x1000538  /* U+0538 ARMENIAN CAPITAL LETTER ET */
#define XK_Armenian_at                0x1000568  /* U+0568 ARMENIAN SMALL LETTER ET */
#define XK_Armenian_TO                0x1000539  /* U+0539 ARMENIAN CAPITAL LETTER TO */
#define XK_Armenian_to                0x1000569  /* U+0569 ARMENIAN SMALL LETTER TO */
#define XK_Armenian_ZHE               0x100053a  /* U+053A ARMENIAN CAPITAL LETTER ZHE */
#define XK_Armenian_zhe               0x100056a  /* U+056A ARMENIAN SMALL LETTER ZHE */
#define XK_Armenian_INI               0x100053b  /* U+053B ARMENIAN CAPITAL LETTER INI */
#define XK_Armenian_ini               0x100056b  /* U+056B ARMENIAN SMALL LETTER INI */
#define XK_Armenian_LYUN              0x100053c  /* U+053C ARMENIAN CAPITAL LETTER LIWN */
#define XK_Armenian_lyun              0x100056c  /* U+056C ARMENIAN SMALL LETTER LIWN */
#define XK_Armenian_KHE               0x100053d  /* U+053D ARMENIAN CAPITAL LETTER XEH */
#define XK_Armenian_khe               0x100056d  /* U+056D ARMENIAN SMALL LETTER XEH */
#define XK_Armenian_TSA               0x100053e  /* U+053E ARMENIAN CAPITAL LETTER CA */
#define XK_Armenian_tsa               0x100056e  /* U+056E ARMENIAN SMALL LETTER CA */
#define XK_Armenian_KEN               0x100053f  /* U+053F ARMENIAN CAPITAL LETTER KEN */
#define XK_Armenian_ken               0x100056f  /* U+056F ARMENIAN SMALL LETTER KEN */
#define XK_Armenian_HO                0x1000540  /* U+0540 ARMENIAN CAPITAL LETTER HO */
#define XK_Armenian_ho                0x1000570  /* U+0570 ARMENIAN SMALL LETTER HO */
#define XK_Armenian_DZA               0x1000541  /* U+0541 ARMENIAN CAPITAL LETTER JA */
#define XK_Armenian_dza               0x1000571  /* U+0571 ARMENIAN SMALL LETTER JA */
#define XK_Armenian_GHAT              0x1000542  /* U+0542 ARMENIAN CAPITAL LETTER GHAD */
#define XK_Armenian_ghat              0x1000572  /* U+0572 ARMENIAN SMALL LETTER GHAD */
#define XK_Armenian_TCHE              0x1000543  /* U+0543 ARMENIAN CAPITAL LETTER CHEH */
#define XK_Armenian_tche              0x1000573  /* U+0573 ARMENIAN SMALL LETTER CHEH */
#define XK_Armenian_MEN               0x1000544  /* U+0544 ARMENIAN CAPITAL LETTER MEN */
#define XK_Armenian_men               0x1000574  /* U+0574 ARMENIAN SMALL LETTER MEN */
#define XK_Armenian_HI                0x1000545  /* U+0545 ARMENIAN CAPITAL LETTER YI */
#define XK_Armenian_hi                0x1000575  /* U+0575 ARMENIAN SMALL LETTER YI */
#define XK_Armenian_NU                0x1000546  /* U+0546 ARMENIAN CAPITAL LETTER NOW */
#define XK_Armenian_nu                0x1000576  /* U+0576 ARMENIAN SMALL LETTER NOW */
#define XK_Armenian_SHA               0x1000547  /* U+0547 ARMENIAN CAPITAL LETTER SHA */
#define XK_Armenian_sha               0x1000577  /* U+0577 ARMENIAN SMALL LETTER SHA */
#define XK_Armenian_VO                0x1000548  /* U+0548 ARMENIAN CAPITAL LETTER VO */
#define XK_Armenian_vo                0x1000578  /* U+0578 ARMENIAN SMALL LETTER VO */
#define XK_Armenian_CHA               0x1000549  /* U+0549 ARMENIAN CAPITAL LETTER CHA */
#define XK_Armenian_cha               0x1000579  /* U+0579 ARMENIAN SMALL LETTER CHA */
#define XK_Armenian_PE                0x100054a  /* U+054A ARMENIAN CAPITAL LETTER PEH */
#define XK_Armenian_pe                0x100057a  /* U+057A ARMENIAN SMALL LETTER PEH */
#define XK_Armenian_JE                0x100054b  /* U+054B ARMENIAN CAPITAL LETTER JHEH */
#define XK_Armenian_je                0x100057b  /* U+057B ARMENIAN SMALL LETTER JHEH */
#define XK_Armenian_RA                0x100054c  /* U+054C ARMENIAN CAPITAL LETTER RA */
#define XK_Armenian_ra                0x100057c  /* U+057C ARMENIAN SMALL LETTER RA */
#define XK_Armenian_SE                0x100054d  /* U+054D ARMENIAN CAPITAL LETTER SEH */
#define XK_Armenian_se                0x100057d  /* U+057D ARMENIAN SMALL LETTER SEH */
#define XK_Armenian_VEV               0x100054e  /* U+054E ARMENIAN CAPITAL LETTER VEW */
#define XK_Armenian_vev               0x100057e  /* U+057E ARMENIAN SMALL LETTER VEW */
#define XK_Armenian_TYUN              0x100054f  /* U+054F ARMENIAN CAPITAL LETTER TIWN */
#define XK_Armenian_tyun              0x100057f  /* U+057F ARMENIAN SMALL LETTER TIWN */
#define XK_Armenian_RE                0x1000550  /* U+0550 ARMENIAN CAPITAL LETTER REH */
#define XK_Armenian_re                0x1000580  /* U+0580 ARMENIAN SMALL LETTER REH */
#define XK_Armenian_TSO               0x1000551  /* U+0551 ARMENIAN CAPITAL LETTER CO */
#define XK_Armenian_tso               0x1000581  /* U+0581 ARMENIAN SMALL LETTER CO */
#define XK_Armenian_VYUN              0x1000552  /* U+0552 ARMENIAN CAPITAL LETTER YIWN */
#define XK_Armenian_vyun              0x1000582  /* U+0582 ARMENIAN SMALL LETTER YIWN */
#define XK_Armenian_PYUR              0x1000553  /* U+0553 ARMENIAN CAPITAL LETTER PIWR */
#define XK_Armenian_pyur              0x1000583  /* U+0583 ARMENIAN SMALL LETTER PIWR */
#define XK_Armenian_KE                0x1000554  /* U+0554 ARMENIAN CAPITAL LETTER KEH */
#define XK_Armenian_ke                0x1000584  /* U+0584 ARMENIAN SMALL LETTER KEH */
#define XK_Armenian_O                 0x1000555  /* U+0555 ARMENIAN CAPITAL LETTER OH */
#define XK_Armenian_o                 0x1000585  /* U+0585 ARMENIAN SMALL LETTER OH */
#define XK_Armenian_FE                0x1000556  /* U+0556 ARMENIAN CAPITAL LETTER FEH */
#define XK_Armenian_fe                0x1000586  /* U+0586 ARMENIAN SMALL LETTER FEH */
#define XK_Armenian_apostrophe        0x100055a  /* U+055A ARMENIAN APOSTROPHE */
#endif /* XK_ARMENIAN */

/*
 * Georgian
 */

#ifdef XK_GEORGIAN
#define XK_Georgian_an                0x10010d0  /* U+10D0 GEORGIAN LETTER AN */
#define XK_Georgian_ban               0x10010d1  /* U+10D1 GEORGIAN LETTER BAN */
#define XK_Georgian_gan               0x10010d2  /* U+10D2 GEORGIAN LETTER GAN */
#define XK_Georgian_don               0x10010d3  /* U+10D3 GEORGIAN LETTER DON */
#define XK_Georgian_en                0x10010d4  /* U+10D4 GEORGIAN LETTER EN */
#define XK_Georgian_vin               0x10010d5  /* U+10D5 GEORGIAN LETTER VIN */
#define XK_Georgian_zen               0x10010d6  /* U+10D6 GEORGIAN LETTER ZEN */
#define XK_Georgian_tan               0x10010d7  /* U+10D7 GEORGIAN LETTER TAN */
#define XK_Georgian_in                0x10010d8  /* U+10D8 GEORGIAN LETTER IN */
#define XK_Georgian_kan               0x10010d9  /* U+10D9 GEORGIAN LETTER KAN */
#define XK_Georgian_las               0x10010da  /* U+10DA GEORGIAN LETTER LAS */
#define XK_Georgian_man               0x10010db  /* U+10DB GEORGIAN LETTER MAN */
#define XK_Georgian_nar               0x10010dc  /* U+10DC GEORGIAN LETTER NAR */
#define XK_Georgian_on                0x10010dd  /* U+10DD GEORGIAN LETTER ON */
#define XK_Georgian_par               0x10010de  /* U+10DE GEORGIAN LETTER PAR */
#define XK_Georgian_zhar              0x10010df  /* U+10DF GEORGIAN LETTER ZHAR */
#define XK_Georgian_rae               0x10010e0  /* U+10E0 GEORGIAN LETTER RAE */
#define XK_Georgian_san               0x10010e1  /* U+10E1 GEORGIAN LETTER SAN */
#define XK_Georgian_tar               0x10010e2  /* U+10E2 GEORGIAN LETTER TAR */
#define XK_Georgian_un                0x10010e3  /* U+10E3 GEORGIAN LETTER UN */
#define XK_Georgian_phar              0x10010e4  /* U+10E4 GEORGIAN LETTER PHAR */
#define XK_Georgian_khar              0x10010e5  /* U+10E5 GEORGIAN LETTER KHAR */
#define XK_Georgian_ghan              0x10010e6  /* U+10E6 GEORGIAN LETTER GHAN */
#define XK_Georgian_qar               0x10010e7  /* U+10E7 GEORGIAN LETTER QAR */
#define XK_Georgian_shin              0x10010e8  /* U+10E8 GEORGIAN LETTER SHIN */
#define XK_Georgian_chin              0x10010e9  /* U+10E9 GEORGIAN LETTER CHIN */
#define XK_Georgian_can               0x10010ea  /* U+10EA GEORGIAN LETTER CAN */
#define XK_Georgian_jil               0x10010eb  /* U+10EB GEORGIAN LETTER JIL */
#define XK_Georgian_cil               0x10010ec  /* U+10EC GEORGIAN LETTER CIL */
#define XK_Georgian_char              0x10010ed  /* U+10ED GEORGIAN LETTER CHAR */
#define XK_Georgian_xan               0x10010ee  /* U+10EE GEORGIAN LETTER XAN */
#define XK_Georgian_jhan              0x10010ef  /* U+10EF GEORGIAN LETTER JHAN */
#define XK_Georgian_hae               0x10010f0  /* U+10F0 GEORGIAN LETTER HAE */
#define XK_Georgian_he                0x10010f1  /* U+10F1 GEORGIAN LETTER HE */
#define XK_Georgian_hie               0x10010f2  /* U+10F2 GEORGIAN LETTER HIE */
#define XK_Georgian_we                0x10010f3  /* U+10F3 GEORGIAN LETTER WE */
#define XK_Georgian_har               0x10010f4  /* U+10F4 GEORGIAN LETTER HAR */
#define XK_Georgian_hoe               0x10010f5  /* U+10F5 GEORGIAN LETTER HOE */
#define XK_Georgian_fi                0x10010f6  /* U+10F6 GEORGIAN LETTER FI */
#endif /* XK_GEORGIAN */

/*
 * Azeri (and other Turkic or Caucasian languages)
 */

#ifdef XK_CAUCASUS
/* latin */
#define XK_Xabovedot                  0x1001e8a  /* U+1E8A LATIN CAPITAL LETTER X WITH DOT ABOVE */
#define XK_Ibreve                     0x100012c  /* U+012C LATIN CAPITAL LETTER I WITH BREVE */
#define XK_Zstroke                    0x10001b5  /* U+01B5 LATIN CAPITAL LETTER Z WITH STROKE */
#define XK_Gcaron                     0x10001e6  /* U+01E6 LATIN CAPITAL LETTER G WITH CARON */
#define XK_Ocaron                     0x10001d1  /* U+01D1 LATIN CAPITAL LETTER O WITH CARON */
#define XK_Obarred                    0x100019f  /* U+019F LATIN CAPITAL LETTER O WITH MIDDLE TILDE */
#define XK_xabovedot                  0x1001e8b  /* U+1E8B LATIN SMALL LETTER X WITH DOT ABOVE */
#define XK_ibreve                     0x100012d  /* U+012D LATIN SMALL LETTER I WITH BREVE */
#define XK_zstroke                    0x10001b6  /* U+01B6 LATIN SMALL LETTER Z WITH STROKE */
#define XK_gcaron                     0x10001e7  /* U+01E7 LATIN SMALL LETTER G WITH CARON */
#define XK_ocaron                     0x10001d2  /* U+01D2 LATIN SMALL LETTER O WITH CARON */
#define XK_obarred                    0x1000275  /* U+0275 LATIN SMALL LETTER BARRED O */
#define XK_SCHWA                      0x100018f  /* U+018F LATIN CAPITAL LETTER SCHWA */
#define XK_schwa                      0x1000259  /* U+0259 LATIN SMALL LETTER SCHWA */
#define XK_EZH                        0x10001b7  /* U+01B7 LATIN CAPITAL LETTER EZH */
#define XK_ezh                        0x1000292  /* U+0292 LATIN SMALL LETTER EZH */
/* those are not really Caucasus */
/* For Inupiak */
#define XK_Lbelowdot                  0x1001e36  /* U+1E36 LATIN CAPITAL LETTER L WITH DOT BELOW */
#define XK_lbelowdot                  0x1001e37  /* U+1E37 LATIN SMALL LETTER L WITH DOT BELOW */
#endif /* XK_CAUCASUS */

/*
 * Vietnamese
 */

#ifdef XK_VIETNAMESE
#define XK_Abelowdot                  0x1001ea0  /* U+1EA0 LATIN CAPITAL LETTER A WITH DOT BELOW */
#define XK_abelowdot                  0x1001ea1  /* U+1EA1 LATIN SMALL LETTER A WITH DOT BELOW */
#define XK_Ahook                      0x1001ea2  /* U+1EA2 LATIN CAPITAL LETTER A WITH HOOK ABOVE */
#define XK_ahook                      0x1001ea3  /* U+1EA3 LATIN SMALL LETTER A WITH HOOK ABOVE */
#define XK_Acircumflexacute           0x1001ea4  /* U+1EA4 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE */
#define XK_acircumflexacute           0x1001ea5  /* U+1EA5 LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE */
#define XK_Acircumflexgrave           0x1001ea6  /* U+1EA6 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE */
#define XK_acircumflexgrave           0x1001ea7  /* U+1EA7 LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE */
#define XK_Acircumflexhook            0x1001ea8  /* U+1EA8 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */
#define XK_acircumflexhook            0x1001ea9  /* U+1EA9 LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */
#define XK_Acircumflextilde           0x1001eaa  /* U+1EAA LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE */
#define XK_acircumflextilde           0x1001eab  /* U+1EAB LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE */
#define XK_Acircumflexbelowdot        0x1001eac  /* U+1EAC LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW */
#define XK_acircumflexbelowdot        0x1001ead  /* U+1EAD LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW */
#define XK_Abreveacute                0x1001eae  /* U+1EAE LATIN CAPITAL LETTER A WITH BREVE AND ACUTE */
#define XK_abreveacute                0x1001eaf  /* U+1EAF LATIN SMALL LETTER A WITH BREVE AND ACUTE */
#define XK_Abrevegrave                0x1001eb0  /* U+1EB0 LATIN CAPITAL LETTER A WITH BREVE AND GRAVE */
#define XK_abrevegrave                0x1001eb1  /* U+1EB1 LATIN SMALL LETTER A WITH BREVE AND GRAVE */
#define XK_Abrevehook                 0x1001eb2  /* U+1EB2 LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE */
#define XK_abrevehook                 0x1001eb3  /* U+1EB3 LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE */
#define XK_Abrevetilde                0x1001eb4  /* U+1EB4 LATIN CAPITAL LETTER A WITH BREVE AND TILDE */
#define XK_abrevetilde                0x1001eb5  /* U+1EB5 LATIN SMALL LETTER A WITH BREVE AND TILDE */
#define XK_Abrevebelowdot             0x1001eb6  /* U+1EB6 LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW */
#define XK_abrevebelowdot             0x1001eb7  /* U+1EB7 LATIN SMALL LETTER A WITH BREVE AND DOT BELOW */
#define XK_Ebelowdot                  0x1001eb8  /* U+1EB8 LATIN CAPITAL LETTER E WITH DOT BELOW */
#define XK_ebelowdot                  0x1001eb9  /* U+1EB9 LATIN SMALL LETTER E WITH DOT BELOW */
#define XK_Ehook                      0x1001eba  /* U+1EBA LATIN CAPITAL LETTER E WITH HOOK ABOVE */
#define XK_ehook                      0x1001ebb  /* U+1EBB LATIN SMALL LETTER E WITH HOOK ABOVE */
#define XK_Etilde                     0x1001ebc  /* U+1EBC LATIN CAPITAL LETTER E WITH TILDE */
#define XK_etilde                     0x1001ebd  /* U+1EBD LATIN SMALL LETTER E WITH TILDE */
#define XK_Ecircumflexacute           0x1001ebe  /* U+1EBE LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE */
#define XK_ecircumflexacute           0x1001ebf  /* U+1EBF LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE */
#define XK_Ecircumflexgrave           0x1001ec0  /* U+1EC0 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE */
#define XK_ecircumflexgrave           0x1001ec1  /* U+1EC1 LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE */
#define XK_Ecircumflexhook            0x1001ec2  /* U+1EC2 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */
#define XK_ecircumflexhook            0x1001ec3  /* U+1EC3 LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */
#define XK_Ecircumflextilde           0x1001ec4  /* U+1EC4 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE */
#define XK_ecircumflextilde           0x1001ec5  /* U+1EC5 LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE */
#define XK_Ecircumflexbelowdot        0x1001ec6  /* U+1EC6 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW */
#define XK_ecircumflexbelowdot        0x1001ec7  /* U+1EC7 LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW */
#define XK_Ihook                      0x1001ec8  /* U+1EC8 LATIN CAPITAL LETTER I WITH HOOK ABOVE */
#define XK_ihook                      0x1001ec9  /* U+1EC9 LATIN SMALL LETTER I WITH HOOK ABOVE */
#define XK_Ibelowdot                  0x1001eca  /* U+1ECA LATIN CAPITAL LETTER I WITH DOT BELOW */
#define XK_ibelowdot                  0x1001ecb  /* U+1ECB LATIN SMALL LETTER I WITH DOT BELOW */
#define XK_Obelowdot                  0x1001ecc  /* U+1ECC LATIN CAPITAL LETTER O WITH DOT BELOW */
#define XK_obelowdot                  0x1001ecd  /* U+1ECD LATIN SMALL LETTER O WITH DOT BELOW */
#define XK_Ohook                      0x1001ece  /* U+1ECE LATIN CAPITAL LETTER O WITH HOOK ABOVE */
#define XK_ohook                      0x1001ecf  /* U+1ECF LATIN SMALL LETTER O WITH HOOK ABOVE */
#define XK_Ocircumflexacute           0x1001ed0  /* U+1ED0 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE */
#define XK_ocircumflexacute           0x1001ed1  /* U+1ED1 LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE */
#define XK_Ocircumflexgrave           0x1001ed2  /* U+1ED2 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE */
#define XK_ocircumflexgrave           0x1001ed3  /* U+1ED3 LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE */
#define XK_Ocircumflexhook            0x1001ed4  /* U+1ED4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */
#define XK_ocircumflexhook            0x1001ed5  /* U+1ED5 LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */
#define XK_Ocircumflextilde           0x1001ed6  /* U+1ED6 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE */
#define XK_ocircumflextilde           0x1001ed7  /* U+1ED7 LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE */
#define XK_Ocircumflexbelowdot        0x1001ed8  /* U+1ED8 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW */
#define XK_ocircumflexbelowdot        0x1001ed9  /* U+1ED9 LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW */
#define XK_Ohornacute                 0x1001eda  /* U+1EDA LATIN CAPITAL LETTER O WITH HORN AND ACUTE */
#define XK_ohornacute                 0x1001edb  /* U+1EDB LATIN SMALL LETTER O WITH HORN AND ACUTE */
#define XK_Ohorngrave                 0x1001edc  /* U+1EDC LATIN CAPITAL LETTER O WITH HORN AND GRAVE */
#define XK_ohorngrave                 0x1001edd  /* U+1EDD LATIN SMALL LETTER O WITH HORN AND GRAVE */
#define XK_Ohornhook                  0x1001ede  /* U+1EDE LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE */
#define XK_ohornhook                  0x1001edf  /* U+1EDF LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE */
#define XK_Ohorntilde                 0x1001ee0  /* U+1EE0 LATIN CAPITAL LETTER O WITH HORN AND TILDE */
#define XK_ohorntilde                 0x1001ee1  /* U+1EE1 LATIN SMALL LETTER O WITH HORN AND TILDE */
#define XK_Ohornbelowdot              0x1001ee2  /* U+1EE2 LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW */
#define XK_ohornbelowdot              0x1001ee3  /* U+1EE3 LATIN SMALL LETTER O WITH HORN AND DOT BELOW */
#define XK_Ubelowdot                  0x1001ee4  /* U+1EE4 LATIN CAPITAL LETTER U WITH DOT BELOW */
#define XK_ubelowdot                  0x1001ee5  /* U+1EE5 LATIN SMALL LETTER U WITH DOT BELOW */
#define XK_Uhook                      0x1001ee6  /* U+1EE6 LATIN CAPITAL LETTER U WITH HOOK ABOVE */
#define XK_uhook                      0x1001ee7  /* U+1EE7 LATIN SMALL LETTER U WITH HOOK ABOVE */
#define XK_Uhornacute                 0x1001ee8  /* U+1EE8 LATIN CAPITAL LETTER U WITH HORN AND ACUTE */
#define XK_uhornacute                 0x1001ee9  /* U+1EE9 LATIN SMALL LETTER U WITH HORN AND ACUTE */
#define XK_Uhorngrave                 0x1001eea  /* U+1EEA LATIN CAPITAL LETTER U WITH HORN AND GRAVE */
#define XK_uhorngrave                 0x1001eeb  /* U+1EEB LATIN SMALL LETTER U WITH HORN AND GRAVE */
#define XK_Uhornhook                  0x1001eec  /* U+1EEC LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE */
#define XK_uhornhook                  0x1001eed  /* U+1EED LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE */
#define XK_Uhorntilde                 0x1001eee  /* U+1EEE LATIN CAPITAL LETTER U WITH HORN AND TILDE */
#define XK_uhorntilde                 0x1001eef  /* U+1EEF LATIN SMALL LETTER U WITH HORN AND TILDE */
#define XK_Uhornbelowdot              0x1001ef0  /* U+1EF0 LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW */
#define XK_uhornbelowdot              0x1001ef1  /* U+1EF1 LATIN SMALL LETTER U WITH HORN AND DOT BELOW */
#define XK_Ybelowdot                  0x1001ef4  /* U+1EF4 LATIN CAPITAL LETTER Y WITH DOT BELOW */
#define XK_ybelowdot                  0x1001ef5  /* U+1EF5 LATIN SMALL LETTER Y WITH DOT BELOW */
#define XK_Yhook                      0x1001ef6  /* U+1EF6 LATIN CAPITAL LETTER Y WITH HOOK ABOVE */
#define XK_yhook                      0x1001ef7  /* U+1EF7 LATIN SMALL LETTER Y WITH HOOK ABOVE */
#define XK_Ytilde                     0x1001ef8  /* U+1EF8 LATIN CAPITAL LETTER Y WITH TILDE */
#define XK_ytilde                     0x1001ef9  /* U+1EF9 LATIN SMALL LETTER Y WITH TILDE */
#define XK_Ohorn                      0x10001a0  /* U+01A0 LATIN CAPITAL LETTER O WITH HORN */
#define XK_ohorn                      0x10001a1  /* U+01A1 LATIN SMALL LETTER O WITH HORN */
#define XK_Uhorn                      0x10001af  /* U+01AF LATIN CAPITAL LETTER U WITH HORN */
#define XK_uhorn                      0x10001b0  /* U+01B0 LATIN SMALL LETTER U WITH HORN */

#endif /* XK_VIETNAMESE */

#ifdef XK_CURRENCY
#define XK_EcuSign                    0x10020a0  /* U+20A0 EURO-CURRENCY SIGN */
#define XK_ColonSign                  0x10020a1  /* U+20A1 COLON SIGN */
#define XK_CruzeiroSign               0x10020a2  /* U+20A2 CRUZEIRO SIGN */
#define XK_FFrancSign                 0x10020a3  /* U+20A3 FRENCH FRANC SIGN */
#define XK_LiraSign                   0x10020a4  /* U+20A4 LIRA SIGN */
#define XK_MillSign                   0x10020a5  /* U+20A5 MILL SIGN */
#define XK_NairaSign                  0x10020a6  /* U+20A6 NAIRA SIGN */
#define XK_PesetaSign                 0x10020a7  /* U+20A7 PESETA SIGN */
#define XK_RupeeSign                  0x10020a8  /* U+20A8 RUPEE SIGN */
#define XK_WonSign                    0x10020a9  /* U+20A9 WON SIGN */
#define XK_NewSheqelSign              0x10020aa  /* U+20AA NEW SHEQEL SIGN */
#define XK_DongSign                   0x10020ab  /* U+20AB DONG SIGN */
#define XK_EuroSign                      0x20ac  /* U+20AC EURO SIGN */
#endif /* XK_CURRENCY */

#ifdef XK_MATHEMATICAL
/* one, two and three are defined above. */
#define XK_zerosuperior               0x1002070  /* U+2070 SUPERSCRIPT ZERO */
#define XK_foursuperior               0x1002074  /* U+2074 SUPERSCRIPT FOUR */
#define XK_fivesuperior               0x1002075  /* U+2075 SUPERSCRIPT FIVE */
#define XK_sixsuperior                0x1002076  /* U+2076 SUPERSCRIPT SIX */
#define XK_sevensuperior              0x1002077  /* U+2077 SUPERSCRIPT SEVEN */
#define XK_eightsuperior              0x1002078  /* U+2078 SUPERSCRIPT EIGHT */
#define XK_ninesuperior               0x1002079  /* U+2079 SUPERSCRIPT NINE */
#define XK_zerosubscript              0x1002080  /* U+2080 SUBSCRIPT ZERO */
#define XK_onesubscript               0x1002081  /* U+2081 SUBSCRIPT ONE */
#define XK_twosubscript               0x1002082  /* U+2082 SUBSCRIPT TWO */
#define XK_threesubscript             0x1002083  /* U+2083 SUBSCRIPT THREE */
#define XK_foursubscript              0x1002084  /* U+2084 SUBSCRIPT FOUR */
#define XK_fivesubscript              0x1002085  /* U+2085 SUBSCRIPT FIVE */
#define XK_sixsubscript               0x1002086  /* U+2086 SUBSCRIPT SIX */
#define XK_sevensubscript             0x1002087  /* U+2087 SUBSCRIPT SEVEN */
#define XK_eightsubscript             0x1002088  /* U+2088 SUBSCRIPT EIGHT */
#define XK_ninesubscript              0x1002089  /* U+2089 SUBSCRIPT NINE */
#define XK_partdifferential           0x1002202  /* U+2202 PARTIAL DIFFERENTIAL */
#define XK_emptyset                   0x1002205  /* U+2205 NULL SET */
#define XK_elementof                  0x1002208  /* U+2208 ELEMENT OF */
#define XK_notelementof               0x1002209  /* U+2209 NOT AN ELEMENT OF */
#define XK_containsas                 0x100220B  /* U+220B CONTAINS AS MEMBER */
#define XK_squareroot                 0x100221A  /* U+221A SQUARE ROOT */
#define XK_cuberoot                   0x100221B  /* U+221B CUBE ROOT */
#define XK_fourthroot                 0x100221C  /* U+221C FOURTH ROOT */
#define XK_dintegral                  0x100222C  /* U+222C DOUBLE INTEGRAL */
#define XK_tintegral                  0x100222D  /* U+222D TRIPLE INTEGRAL */
#define XK_because                    0x1002235  /* U+2235 BECAUSE */
#define XK_approxeq                   0x1002248  /* U+2245 ALMOST EQUAL TO */
#define XK_notapproxeq                0x1002247  /* U+2247 NOT ALMOST EQUAL TO */
#define XK_notidentical               0x1002262  /* U+2262 NOT IDENTICAL TO */
#define XK_stricteq                   0x1002263  /* U+2263 STRICTLY EQUIVALENT TO */
#endif /* XK_MATHEMATICAL */

#ifdef XK_BRAILLE
#define XK_braille_dot_1                 0xfff1
#define XK_braille_dot_2                 0xfff2
#define XK_braille_dot_3                 0xfff3
#define XK_braille_dot_4                 0xfff4
#define XK_braille_dot_5                 0xfff5
#define XK_braille_dot_6                 0xfff6
#define XK_braille_dot_7                 0xfff7
#define XK_braille_dot_8                 0xfff8
#define XK_braille_dot_9                 0xfff9
#define XK_braille_dot_10                0xfffa
#define XK_braille_blank              0x1002800  /* U+2800 BRAILLE PATTERN BLANK */
#define XK_braille_dots_1             0x1002801  /* U+2801 BRAILLE PATTERN DOTS-1 */
#define XK_braille_dots_2             0x1002802  /* U+2802 BRAILLE PATTERN DOTS-2 */
#define XK_braille_dots_12            0x1002803  /* U+2803 BRAILLE PATTERN DOTS-12 */
#define XK_braille_dots_3             0x1002804  /* U+2804 BRAILLE PATTERN DOTS-3 */
#define XK_braille_dots_13            0x1002805  /* U+2805 BRAILLE PATTERN DOTS-13 */
#define XK_braille_dots_23            0x1002806  /* U+2806 BRAILLE PATTERN DOTS-23 */
#define XK_braille_dots_123           0x1002807  /* U+2807 BRAILLE PATTERN DOTS-123 */
#define XK_braille_dots_4             0x1002808  /* U+2808 BRAILLE PATTERN DOTS-4 */
#define XK_braille_dots_14            0x1002809  /* U+2809 BRAILLE PATTERN DOTS-14 */
#define XK_braille_dots_24            0x100280a  /* U+280a BRAILLE PATTERN DOTS-24 */
#define XK_braille_dots_124           0x100280b  /* U+280b BRAILLE PATTERN DOTS-124 */
#define XK_braille_dots_34            0x100280c  /* U+280c BRAILLE PATTERN DOTS-34 */
#define XK_braille_dots_134           0x100280d  /* U+280d BRAILLE PATTERN DOTS-134 */
#define XK_braille_dots_234           0x100280e  /* U+280e BRAILLE PATTERN DOTS-234 */
#define XK_braille_dots_1234          0x100280f  /* U+280f BRAILLE PATTERN DOTS-1234 */
#define XK_braille_dots_5             0x1002810  /* U+2810 BRAILLE PATTERN DOTS-5 */
#define XK_braille_dots_15            0x1002811  /* U+2811 BRAILLE PATTERN DOTS-15 */
#define XK_braille_dots_25            0x1002812  /* U+2812 BRAILLE PATTERN DOTS-25 */
#define XK_braille_dots_125           0x1002813  /* U+2813 BRAILLE PATTERN DOTS-125 */
#define XK_braille_dots_35            0x1002814  /* U+2814 BRAILLE PATTERN DOTS-35 */
#define XK_braille_dots_135           0x1002815  /* U+2815 BRAILLE PATTERN DOTS-135 */
#define XK_braille_dots_235           0x1002816  /* U+2816 BRAILLE PATTERN DOTS-235 */
#define XK_braille_dots_1235          0x1002817  /* U+2817 BRAILLE PATTERN DOTS-1235 */
#define XK_braille_dots_45            0x1002818  /* U+2818 BRAILLE PATTERN DOTS-45 */
#define XK_braille_dots_145           0x1002819  /* U+2819 BRAILLE PATTERN DOTS-145 */
#define XK_braille_dots_245           0x100281a  /* U+281a BRAILLE PATTERN DOTS-245 */
#define XK_braille_dots_1245          0x100281b  /* U+281b BRAILLE PATTERN DOTS-1245 */
#define XK_braille_dots_345           0x100281c  /* U+281c BRAILLE PATTERN DOTS-345 */
#define XK_braille_dots_1345          0x100281d  /* U+281d BRAILLE PATTERN DOTS-1345 */
#define XK_braille_dots_2345          0x100281e  /* U+281e BRAILLE PATTERN DOTS-2345 */
#define XK_braille_dots_12345         0x100281f  /* U+281f BRAILLE PATTERN DOTS-12345 */
#define XK_braille_dots_6             0x1002820  /* U+2820 BRAILLE PATTERN DOTS-6 */
#define XK_braille_dots_16            0x1002821  /* U+2821 BRAILLE PATTERN DOTS-16 */
#define XK_braille_dots_26            0x1002822  /* U+2822 BRAILLE PATTERN DOTS-26 */
#define XK_braille_dots_126           0x1002823  /* U+2823 BRAILLE PATTERN DOTS-126 */
#define XK_braille_dots_36            0x1002824  /* U+2824 BRAILLE PATTERN DOTS-36 */
#define XK_braille_dots_136           0x1002825  /* U+2825 BRAILLE PATTERN DOTS-136 */
#define XK_braille_dots_236           0x1002826  /* U+2826 BRAILLE PATTERN DOTS-236 */
#define XK_braille_dots_1236          0x1002827  /* U+2827 BRAILLE PATTERN DOTS-1236 */
#define XK_braille_dots_46            0x1002828  /* U+2828 BRAILLE PATTERN DOTS-46 */
#define XK_braille_dots_146           0x1002829  /* U+2829 BRAILLE PATTERN DOTS-146 */
#define XK_braille_dots_246           0x100282a  /* U+282a BRAILLE PATTERN DOTS-246 */
#define XK_braille_dots_1246          0x100282b  /* U+282b BRAILLE PATTERN DOTS-1246 */
#define XK_braille_dots_346           0x100282c  /* U+282c BRAILLE PATTERN DOTS-346 */
#define XK_braille_dots_1346          0x100282d  /* U+282d BRAILLE PATTERN DOTS-1346 */
#define XK_braille_dots_2346          0x100282e  /* U+282e BRAILLE PATTERN DOTS-2346 */
#define XK_braille_dots_12346         0x100282f  /* U+282f BRAILLE PATTERN DOTS-12346 */
#define XK_braille_dots_56            0x1002830  /* U+2830 BRAILLE PATTERN DOTS-56 */
#define XK_braille_dots_156           0x1002831  /* U+2831 BRAILLE PATTERN DOTS-156 */
#define XK_braille_dots_256           0x1002832  /* U+2832 BRAILLE PATTERN DOTS-256 */
#define XK_braille_dots_1256          0x1002833  /* U+2833 BRAILLE PATTERN DOTS-1256 */
#define XK_braille_dots_356           0x1002834  /* U+2834 BRAILLE PATTERN DOTS-356 */
#define XK_braille_dots_1356          0x1002835  /* U+2835 BRAILLE PATTERN DOTS-1356 */
#define XK_braille_dots_2356          0x1002836  /* U+2836 BRAILLE PATTERN DOTS-2356 */
#define XK_braille_dots_12356         0x1002837  /* U+2837 BRAILLE PATTERN DOTS-12356 */
#define XK_braille_dots_456           0x1002838  /* U+2838 BRAILLE PATTERN DOTS-456 */
#define XK_braille_dots_1456          0x1002839  /* U+2839 BRAILLE PATTERN DOTS-1456 */
#define XK_braille_dots_2456          0x100283a  /* U+283a BRAILLE PATTERN DOTS-2456 */
#define XK_braille_dots_12456         0x100283b  /* U+283b BRAILLE PATTERN DOTS-12456 */
#define XK_braille_dots_3456          0x100283c  /* U+283c BRAILLE PATTERN DOTS-3456 */
#define XK_braille_dots_13456         0x100283d  /* U+283d BRAILLE PATTERN DOTS-13456 */
#define XK_braille_dots_23456         0x100283e  /* U+283e BRAILLE PATTERN DOTS-23456 */
#define XK_braille_dots_123456        0x100283f  /* U+283f BRAILLE PATTERN DOTS-123456 */
#define XK_braille_dots_7             0x1002840  /* U+2840 BRAILLE PATTERN DOTS-7 */
#define XK_braille_dots_17            0x1002841  /* U+2841 BRAILLE PATTERN DOTS-17 */
#define XK_braille_dots_27            0x1002842  /* U+2842 BRAILLE PATTERN DOTS-27 */
#define XK_braille_dots_127           0x1002843  /* U+2843 BRAILLE PATTERN DOTS-127 */
#define XK_braille_dots_37            0x1002844  /* U+2844 BRAILLE PATTERN DOTS-37 */
#define XK_braille_dots_137           0x1002845  /* U+2845 BRAILLE PATTERN DOTS-137 */
#define XK_braille_dots_237           0x1002846  /* U+2846 BRAILLE PATTERN DOTS-237 */
#define XK_braille_dots_1237          0x1002847  /* U+2847 BRAILLE PATTERN DOTS-1237 */
#define XK_braille_dots_47            0x1002848  /* U+2848 BRAILLE PATTERN DOTS-47 */
#define XK_braille_dots_147           0x1002849  /* U+2849 BRAILLE PATTERN DOTS-147 */
#define XK_braille_dots_247           0x100284a  /* U+284a BRAILLE PATTERN DOTS-247 */
#define XK_braille_dots_1247          0x100284b  /* U+284b BRAILLE PATTERN DOTS-1247 */
#define XK_braille_dots_347           0x100284c  /* U+284c BRAILLE PATTERN DOTS-347 */
#define XK_braille_dots_1347          0x100284d  /* U+284d BRAILLE PATTERN DOTS-1347 */
#define XK_braille_dots_2347          0x100284e  /* U+284e BRAILLE PATTERN DOTS-2347 */
#define XK_braille_dots_12347         0x100284f  /* U+284f BRAILLE PATTERN DOTS-12347 */
#define XK_braille_dots_57            0x1002850  /* U+2850 BRAILLE PATTERN DOTS-57 */
#define XK_braille_dots_157           0x1002851  /* U+2851 BRAILLE PATTERN DOTS-157 */
#define XK_braille_dots_257           0x1002852  /* U+2852 BRAILLE PATTERN DOTS-257 */
#define XK_braille_dots_1257          0x1002853  /* U+2853 BRAILLE PATTERN DOTS-1257 */
#define XK_braille_dots_357           0x1002854  /* U+2854 BRAILLE PATTERN DOTS-357 */
#define XK_braille_dots_1357          0x1002855  /* U+2855 BRAILLE PATTERN DOTS-1357 */
#define XK_braille_dots_2357          0x1002856  /* U+2856 BRAILLE PATTERN DOTS-2357 */
#define XK_braille_dots_12357         0x1002857  /* U+2857 BRAILLE PATTERN DOTS-12357 */
#define XK_braille_dots_457           0x1002858  /* U+2858 BRAILLE PATTERN DOTS-457 */
#define XK_braille_dots_1457          0x1002859  /* U+2859 BRAILLE PATTERN DOTS-1457 */
#define XK_braille_dots_2457          0x100285a  /* U+285a BRAILLE PATTERN DOTS-2457 */
#define XK_braille_dots_12457         0x100285b  /* U+285b BRAILLE PATTERN DOTS-12457 */
#define XK_braille_dots_3457          0x100285c  /* U+285c BRAILLE PATTERN DOTS-3457 */
#define XK_braille_dots_13457         0x100285d  /* U+285d BRAILLE PATTERN DOTS-13457 */
#define XK_braille_dots_23457         0x100285e  /* U+285e BRAILLE PATTERN DOTS-23457 */
#define XK_braille_dots_123457        0x100285f  /* U+285f BRAILLE PATTERN DOTS-123457 */
#define XK_braille_dots_67            0x1002860  /* U+2860 BRAILLE PATTERN DOTS-67 */
#define XK_braille_dots_167           0x1002861  /* U+2861 BRAILLE PATTERN DOTS-167 */
#define XK_braille_dots_267           0x1002862  /* U+2862 BRAILLE PATTERN DOTS-267 */
#define XK_braille_dots_1267          0x1002863  /* U+2863 BRAILLE PATTERN DOTS-1267 */
#define XK_braille_dots_367           0x1002864  /* U+2864 BRAILLE PATTERN DOTS-367 */
#define XK_braille_dots_1367          0x1002865  /* U+2865 BRAILLE PATTERN DOTS-1367 */
#define XK_braille_dots_2367          0x1002866  /* U+2866 BRAILLE PATTERN DOTS-2367 */
#define XK_braille_dots_12367         0x1002867  /* U+2867 BRAILLE PATTERN DOTS-12367 */
#define XK_braille_dots_467           0x1002868  /* U+2868 BRAILLE PATTERN DOTS-467 */
#define XK_braille_dots_1467          0x1002869  /* U+2869 BRAILLE PATTERN DOTS-1467 */
#define XK_braille_dots_2467          0x100286a  /* U+286a BRAILLE PATTERN DOTS-2467 */
#define XK_braille_dots_12467         0x100286b  /* U+286b BRAILLE PATTERN DOTS-12467 */
#define XK_braille_dots_3467          0x100286c  /* U+286c BRAILLE PATTERN DOTS-3467 */
#define XK_braille_dots_13467         0x100286d  /* U+286d BRAILLE PATTERN DOTS-13467 */
#define XK_braille_dots_23467         0x100286e  /* U+286e BRAILLE PATTERN DOTS-23467 */
#define XK_braille_dots_123467        0x100286f  /* U+286f BRAILLE PATTERN DOTS-123467 */
#define XK_braille_dots_567           0x1002870  /* U+2870 BRAILLE PATTERN DOTS-567 */
#define XK_braille_dots_1567          0x1002871  /* U+2871 BRAILLE PATTERN DOTS-1567 */
#define XK_braille_dots_2567          0x1002872  /* U+2872 BRAILLE PATTERN DOTS-2567 */
#define XK_braille_dots_12567         0x1002873  /* U+2873 BRAILLE PATTERN DOTS-12567 */
#define XK_braille_dots_3567          0x1002874  /* U+2874 BRAILLE PATTERN DOTS-3567 */
#define XK_braille_dots_13567         0x1002875  /* U+2875 BRAILLE PATTERN DOTS-13567 */
#define XK_braille_dots_23567         0x1002876  /* U+2876 BRAILLE PATTERN DOTS-23567 */
#define XK_braille_dots_123567        0x1002877  /* U+2877 BRAILLE PATTERN DOTS-123567 */
#define XK_braille_dots_4567          0x1002878  /* U+2878 BRAILLE PATTERN DOTS-4567 */
#define XK_braille_dots_14567         0x1002879  /* U+2879 BRAILLE PATTERN DOTS-14567 */
#define XK_braille_dots_24567         0x100287a  /* U+287a BRAILLE PATTERN DOTS-24567 */
#define XK_braille_dots_124567        0x100287b  /* U+287b BRAILLE PATTERN DOTS-124567 */
#define XK_braille_dots_34567         0x100287c  /* U+287c BRAILLE PATTERN DOTS-34567 */
#define XK_braille_dots_134567        0x100287d  /* U+287d BRAILLE PATTERN DOTS-134567 */
#define XK_braille_dots_234567        0x100287e  /* U+287e BRAILLE PATTERN DOTS-234567 */
#define XK_braille_dots_1234567       0x100287f  /* U+287f BRAILLE PATTERN DOTS-1234567 */
#define XK_braille_dots_8             0x1002880  /* U+2880 BRAILLE PATTERN DOTS-8 */
#define XK_braille_dots_18            0x1002881  /* U+2881 BRAILLE PATTERN DOTS-18 */
#define XK_braille_dots_28            0x1002882  /* U+2882 BRAILLE PATTERN DOTS-28 */
#define XK_braille_dots_128           0x1002883  /* U+2883 BRAILLE PATTERN DOTS-128 */
#define XK_braille_dots_38            0x1002884  /* U+2884 BRAILLE PATTERN DOTS-38 */
#define XK_braille_dots_138           0x1002885  /* U+2885 BRAILLE PATTERN DOTS-138 */
#define XK_braille_dots_238           0x1002886  /* U+2886 BRAILLE PATTERN DOTS-238 */
#define XK_braille_dots_1238          0x1002887  /* U+2887 BRAILLE PATTERN DOTS-1238 */
#define XK_braille_dots_48            0x1002888  /* U+2888 BRAILLE PATTERN DOTS-48 */
#define XK_braille_dots_148           0x1002889  /* U+2889 BRAILLE PATTERN DOTS-148 */
#define XK_braille_dots_248           0x100288a  /* U+288a BRAILLE PATTERN DOTS-248 */
#define XK_braille_dots_1248          0x100288b  /* U+288b BRAILLE PATTERN DOTS-1248 */
#define XK_braille_dots_348           0x100288c  /* U+288c BRAILLE PATTERN DOTS-348 */
#define XK_braille_dots_1348          0x100288d  /* U+288d BRAILLE PATTERN DOTS-1348 */
#define XK_braille_dots_2348          0x100288e  /* U+288e BRAILLE PATTERN DOTS-2348 */
#define XK_braille_dots_12348         0x100288f  /* U+288f BRAILLE PATTERN DOTS-12348 */
#define XK_braille_dots_58            0x1002890  /* U+2890 BRAILLE PATTERN DOTS-58 */
#define XK_braille_dots_158           0x1002891  /* U+2891 BRAILLE PATTERN DOTS-158 */
#define XK_braille_dots_258           0x1002892  /* U+2892 BRAILLE PATTERN DOTS-258 */
#define XK_braille_dots_1258          0x1002893  /* U+2893 BRAILLE PATTERN DOTS-1258 */
#define XK_braille_dots_358           0x1002894  /* U+2894 BRAILLE PATTERN DOTS-358 */
#define XK_braille_dots_1358          0x1002895  /* U+2895 BRAILLE PATTERN DOTS-1358 */
#define XK_braille_dots_2358          0x1002896  /* U+2896 BRAILLE PATTERN DOTS-2358 */
#define XK_braille_dots_12358         0x1002897  /* U+2897 BRAILLE PATTERN DOTS-12358 */
#define XK_braille_dots_458           0x1002898  /* U+2898 BRAILLE PATTERN DOTS-458 */
#define XK_braille_dots_1458          0x1002899  /* U+2899 BRAILLE PATTERN DOTS-1458 */
#define XK_braille_dots_2458          0x100289a  /* U+289a BRAILLE PATTERN DOTS-2458 */
#define XK_braille_dots_12458         0x100289b  /* U+289b BRAILLE PATTERN DOTS-12458 */
#define XK_braille_dots_3458          0x100289c  /* U+289c BRAILLE PATTERN DOTS-3458 */
#define XK_braille_dots_13458         0x100289d  /* U+289d BRAILLE PATTERN DOTS-13458 */
#define XK_braille_dots_23458         0x100289e  /* U+289e BRAILLE PATTERN DOTS-23458 */
#define XK_braille_dots_123458        0x100289f  /* U+289f BRAILLE PATTERN DOTS-123458 */
#define XK_braille_dots_68            0x10028a0  /* U+28a0 BRAILLE PATTERN DOTS-68 */
#define XK_braille_dots_168           0x10028a1  /* U+28a1 BRAILLE PATTERN DOTS-168 */
#define XK_braille_dots_268           0x10028a2  /* U+28a2 BRAILLE PATTERN DOTS-268 */
#define XK_braille_dots_1268          0x10028a3  /* U+28a3 BRAILLE PATTERN DOTS-1268 */
#define XK_braille_dots_368           0x10028a4  /* U+28a4 BRAILLE PATTERN DOTS-368 */
#define XK_braille_dots_1368          0x10028a5  /* U+28a5 BRAILLE PATTERN DOTS-1368 */
#define XK_braille_dots_2368          0x10028a6  /* U+28a6 BRAILLE PATTERN DOTS-2368 */
#define XK_braille_dots_12368         0x10028a7  /* U+28a7 BRAILLE PATTERN DOTS-12368 */
#define XK_braille_dots_468           0x10028a8  /* U+28a8 BRAILLE PATTERN DOTS-468 */
#define XK_braille_dots_1468          0x10028a9  /* U+28a9 BRAILLE PATTERN DOTS-1468 */
#define XK_braille_dots_2468          0x10028aa  /* U+28aa BRAILLE PATTERN DOTS-2468 */
#define XK_braille_dots_12468         0x10028ab  /* U+28ab BRAILLE PATTERN DOTS-12468 */
#define XK_braille_dots_3468          0x10028ac  /* U+28ac BRAILLE PATTERN DOTS-3468 */
#define XK_braille_dots_13468         0x10028ad  /* U+28ad BRAILLE PATTERN DOTS-13468 */
#define XK_braille_dots_23468         0x10028ae  /* U+28ae BRAILLE PATTERN DOTS-23468 */
#define XK_braille_dots_123468        0x10028af  /* U+28af BRAILLE PATTERN DOTS-123468 */
#define XK_braille_dots_568           0x10028b0  /* U+28b0 BRAILLE PATTERN DOTS-568 */
#define XK_braille_dots_1568          0x10028b1  /* U+28b1 BRAILLE PATTERN DOTS-1568 */
#define XK_braille_dots_2568          0x10028b2  /* U+28b2 BRAILLE PATTERN DOTS-2568 */
#define XK_braille_dots_12568         0x10028b3  /* U+28b3 BRAILLE PATTERN DOTS-12568 */
#define XK_braille_dots_3568          0x10028b4  /* U+28b4 BRAILLE PATTERN DOTS-3568 */
#define XK_braille_dots_13568         0x10028b5  /* U+28b5 BRAILLE PATTERN DOTS-13568 */
#define XK_braille_dots_23568         0x10028b6  /* U+28b6 BRAILLE PATTERN DOTS-23568 */
#define XK_braille_dots_123568        0x10028b7  /* U+28b7 BRAILLE PATTERN DOTS-123568 */
#define XK_braille_dots_4568          0x10028b8  /* U+28b8 BRAILLE PATTERN DOTS-4568 */
#define XK_braille_dots_14568         0x10028b9  /* U+28b9 BRAILLE PATTERN DOTS-14568 */
#define XK_braille_dots_24568         0x10028ba  /* U+28ba BRAILLE PATTERN DOTS-24568 */
#define XK_braille_dots_124568        0x10028bb  /* U+28bb BRAILLE PATTERN DOTS-124568 */
#define XK_braille_dots_34568         0x10028bc  /* U+28bc BRAILLE PATTERN DOTS-34568 */
#define XK_braille_dots_134568        0x10028bd  /* U+28bd BRAILLE PATTERN DOTS-134568 */
#define XK_braille_dots_234568        0x10028be  /* U+28be BRAILLE PATTERN DOTS-234568 */
#define XK_braille_dots_1234568       0x10028bf  /* U+28bf BRAILLE PATTERN DOTS-1234568 */
#define XK_braille_dots_78            0x10028c0  /* U+28c0 BRAILLE PATTERN DOTS-78 */
#define XK_braille_dots_178           0x10028c1  /* U+28c1 BRAILLE PATTERN DOTS-178 */
#define XK_braille_dots_278           0x10028c2  /* U+28c2 BRAILLE PATTERN DOTS-278 */
#define XK_braille_dots_1278          0x10028c3  /* U+28c3 BRAILLE PATTERN DOTS-1278 */
#define XK_braille_dots_378           0x10028c4  /* U+28c4 BRAILLE PATTERN DOTS-378 */
#define XK_braille_dots_1378          0x10028c5  /* U+28c5 BRAILLE PATTERN DOTS-1378 */
#define XK_braille_dots_2378          0x10028c6  /* U+28c6 BRAILLE PATTERN DOTS-2378 */
#define XK_braille_dots_12378         0x10028c7  /* U+28c7 BRAILLE PATTERN DOTS-12378 */
#define XK_braille_dots_478           0x10028c8  /* U+28c8 BRAILLE PATTERN DOTS-478 */
#define XK_braille_dots_1478          0x10028c9  /* U+28c9 BRAILLE PATTERN DOTS-1478 */
#define XK_braille_dots_2478          0x10028ca  /* U+28ca BRAILLE PATTERN DOTS-2478 */
#define XK_braille_dots_12478         0x10028cb  /* U+28cb BRAILLE PATTERN DOTS-12478 */
#define XK_braille_dots_3478          0x10028cc  /* U+28cc BRAILLE PATTERN DOTS-3478 */
#define XK_braille_dots_13478         0x10028cd  /* U+28cd BRAILLE PATTERN DOTS-13478 */
#define XK_braille_dots_23478         0x10028ce  /* U+28ce BRAILLE PATTERN DOTS-23478 */
#define XK_braille_dots_123478        0x10028cf  /* U+28cf BRAILLE PATTERN DOTS-123478 */
#define XK_braille_dots_578           0x10028d0  /* U+28d0 BRAILLE PATTERN DOTS-578 */
#define XK_braille_dots_1578          0x10028d1  /* U+28d1 BRAILLE PATTERN DOTS-1578 */
#define XK_braille_dots_2578          0x10028d2  /* U+28d2 BRAILLE PATTERN DOTS-2578 */
#define XK_braille_dots_12578         0x10028d3  /* U+28d3 BRAILLE PATTERN DOTS-12578 */
#define XK_braille_dots_3578          0x10028d4  /* U+28d4 BRAILLE PATTERN DOTS-3578 */
#define XK_braille_dots_13578         0x10028d5  /* U+28d5 BRAILLE PATTERN DOTS-13578 */
#define XK_braille_dots_23578         0x10028d6  /* U+28d6 BRAILLE PATTERN DOTS-23578 */
#define XK_braille_dots_123578        0x10028d7  /* U+28d7 BRAILLE PATTERN DOTS-123578 */
#define XK_braille_dots_4578          0x10028d8  /* U+28d8 BRAILLE PATTERN DOTS-4578 */
#define XK_braille_dots_14578         0x10028d9  /* U+28d9 BRAILLE PATTERN DOTS-14578 */
#define XK_braille_dots_24578         0x10028da  /* U+28da BRAILLE PATTERN DOTS-24578 */
#define XK_braille_dots_124578        0x10028db  /* U+28db BRAILLE PATTERN DOTS-124578 */
#define XK_braille_dots_34578         0x10028dc  /* U+28dc BRAILLE PATTERN DOTS-34578 */
#define XK_braille_dots_134578        0x10028dd  /* U+28dd BRAILLE PATTERN DOTS-134578 */
#define XK_braille_dots_234578        0x10028de  /* U+28de BRAILLE PATTERN DOTS-234578 */
#define XK_braille_dots_1234578       0x10028df  /* U+28df BRAILLE PATTERN DOTS-1234578 */
#define XK_braille_dots_678           0x10028e0  /* U+28e0 BRAILLE PATTERN DOTS-678 */
#define XK_braille_dots_1678          0x10028e1  /* U+28e1 BRAILLE PATTERN DOTS-1678 */
#define XK_braille_dots_2678          0x10028e2  /* U+28e2 BRAILLE PATTERN DOTS-2678 */
#define XK_braille_dots_12678         0x10028e3  /* U+28e3 BRAILLE PATTERN DOTS-12678 */
#define XK_braille_dots_3678          0x10028e4  /* U+28e4 BRAILLE PATTERN DOTS-3678 */
#define XK_braille_dots_13678         0x10028e5  /* U+28e5 BRAILLE PATTERN DOTS-13678 */
#define XK_braille_dots_23678         0x10028e6  /* U+28e6 BRAILLE PATTERN DOTS-23678 */
#define XK_braille_dots_123678        0x10028e7  /* U+28e7 BRAILLE PATTERN DOTS-123678 */
#define XK_braille_dots_4678          0x10028e8  /* U+28e8 BRAILLE PATTERN DOTS-4678 */
#define XK_braille_dots_14678         0x10028e9  /* U+28e9 BRAILLE PATTERN DOTS-14678 */
#define XK_braille_dots_24678         0x10028ea  /* U+28ea BRAILLE PATTERN DOTS-24678 */
#define XK_braille_dots_124678        0x10028eb  /* U+28eb BRAILLE PATTERN DOTS-124678 */
#define XK_braille_dots_34678         0x10028ec  /* U+28ec BRAILLE PATTERN DOTS-34678 */
#define XK_braille_dots_134678        0x10028ed  /* U+28ed BRAILLE PATTERN DOTS-134678 */
#define XK_braille_dots_234678        0x10028ee  /* U+28ee BRAILLE PATTERN DOTS-234678 */
#define XK_braille_dots_1234678       0x10028ef  /* U+28ef BRAILLE PATTERN DOTS-1234678 */
#define XK_braille_dots_5678          0x10028f0  /* U+28f0 BRAILLE PATTERN DOTS-5678 */
#define XK_braille_dots_15678         0x10028f1  /* U+28f1 BRAILLE PATTERN DOTS-15678 */
#define XK_braille_dots_25678         0x10028f2  /* U+28f2 BRAILLE PATTERN DOTS-25678 */
#define XK_braille_dots_125678        0x10028f3  /* U+28f3 BRAILLE PATTERN DOTS-125678 */
#define XK_braille_dots_35678         0x10028f4  /* U+28f4 BRAILLE PATTERN DOTS-35678 */
#define XK_braille_dots_135678        0x10028f5  /* U+28f5 BRAILLE PATTERN DOTS-135678 */
#define XK_braille_dots_235678        0x10028f6  /* U+28f6 BRAILLE PATTERN DOTS-235678 */
#define XK_braille_dots_1235678       0x10028f7  /* U+28f7 BRAILLE PATTERN DOTS-1235678 */
#define XK_braille_dots_45678         0x10028f8  /* U+28f8 BRAILLE PATTERN DOTS-45678 */
#define XK_braille_dots_145678        0x10028f9  /* U+28f9 BRAILLE PATTERN DOTS-145678 */
#define XK_braille_dots_245678        0x10028fa  /* U+28fa BRAILLE PATTERN DOTS-245678 */
#define XK_braille_dots_1245678       0x10028fb  /* U+28fb BRAILLE PATTERN DOTS-1245678 */
#define XK_braille_dots_345678        0x10028fc  /* U+28fc BRAILLE PATTERN DOTS-345678 */
#define XK_braille_dots_1345678       0x10028fd  /* U+28fd BRAILLE PATTERN DOTS-1345678 */
#define XK_braille_dots_2345678       0x10028fe  /* U+28fe BRAILLE PATTERN DOTS-2345678 */
#define XK_braille_dots_12345678      0x10028ff  /* U+28ff BRAILLE PATTERN DOTS-12345678 */
#endif /* XK_BRAILLE */

/*
 * Sinhala (http://unicode.org/charts/PDF/U0D80.pdf)
 * http://www.nongnu.org/sinhala/doc/transliteration/sinhala-transliteration_6.html
 */

#ifdef XK_SINHALA
#define XK_Sinh_ng            0x1000d82  /* U+0D82 SINHALA ANUSVARAYA */
#define XK_Sinh_h2            0x1000d83  /* U+0D83 SINHALA VISARGAYA */
#define XK_Sinh_a             0x1000d85  /* U+0D85 SINHALA AYANNA */
#define XK_Sinh_aa            0x1000d86  /* U+0D86 SINHALA AAYANNA */
#define XK_Sinh_ae            0x1000d87  /* U+0D87 SINHALA AEYANNA */
#define XK_Sinh_aee           0x1000d88  /* U+0D88 SINHALA AEEYANNA */
#define XK_Sinh_i             0x1000d89  /* U+0D89 SINHALA IYANNA */
#define XK_Sinh_ii            0x1000d8a  /* U+0D8A SINHALA IIYANNA */
#define XK_Sinh_u             0x1000d8b  /* U+0D8B SINHALA UYANNA */
#define XK_Sinh_uu            0x1000d8c  /* U+0D8C SINHALA UUYANNA */
#define XK_Sinh_ri            0x1000d8d  /* U+0D8D SINHALA IRUYANNA */
#define XK_Sinh_rii           0x1000d8e  /* U+0D8E SINHALA IRUUYANNA */
#define XK_Sinh_lu            0x1000d8f  /* U+0D8F SINHALA ILUYANNA */
#define XK_Sinh_luu           0x1000d90  /* U+0D90 SINHALA ILUUYANNA */
#define XK_Sinh_e             0x1000d91  /* U+0D91 SINHALA EYANNA */
#define XK_Sinh_ee            0x1000d92  /* U+0D92 SINHALA EEYANNA */
#define XK_Sinh_ai            0x1000d93  /* U+0D93 SINHALA AIYANNA */
#define XK_Sinh_o             0x1000d94  /* U+0D94 SINHALA OYANNA */
#define XK_Sinh_oo            0x1000d95  /* U+0D95 SINHALA OOYANNA */
#define XK_Sinh_au            0x1000d96  /* U+0D96 SINHALA AUYANNA */
#define XK_Sinh_ka            0x1000d9a  /* U+0D9A SINHALA KAYANNA */
#define XK_Sinh_kha           0x1000d9b  /* U+0D9B SINHALA MAHA. KAYANNA */
#define XK_Sinh_ga            0x1000d9c  /* U+0D9C SINHALA GAYANNA */
#define XK_Sinh_gha           0x1000d9d  /* U+0D9D SINHALA MAHA. GAYANNA */
#define XK_Sinh_ng2           0x1000d9e  /* U+0D9E SINHALA KANTAJA NAASIKYAYA */
#define XK_Sinh_nga           0x1000d9f  /* U+0D9F SINHALA SANYAKA GAYANNA */
#define XK_Sinh_ca            0x1000da0  /* U+0DA0 SINHALA CAYANNA */
#define XK_Sinh_cha           0x1000da1  /* U+0DA1 SINHALA MAHA. CAYANNA */
#define XK_Sinh_ja            0x1000da2  /* U+0DA2 SINHALA JAYANNA */
#define XK_Sinh_jha           0x1000da3  /* U+0DA3 SINHALA MAHA. JAYANNA */
#define XK_Sinh_nya           0x1000da4  /* U+0DA4 SINHALA TAALUJA NAASIKYAYA */
#define XK_Sinh_jnya          0x1000da5  /* U+0DA5 SINHALA TAALUJA SANYOOGA NAASIKYAYA */
#define XK_Sinh_nja           0x1000da6  /* U+0DA6 SINHALA SANYAKA JAYANNA */
#define XK_Sinh_tta           0x1000da7  /* U+0DA7 SINHALA TTAYANNA */
#define XK_Sinh_ttha          0x1000da8  /* U+0DA8 SINHALA MAHA. TTAYANNA */
#define XK_Sinh_dda           0x1000da9  /* U+0DA9 SINHALA DDAYANNA */
#define XK_Sinh_ddha          0x1000daa  /* U+0DAA SINHALA MAHA. DDAYANNA */
#define XK_Sinh_nna           0x1000dab  /* U+0DAB SINHALA MUURDHAJA NAYANNA */
#define XK_Sinh_ndda          0x1000dac  /* U+0DAC SINHALA SANYAKA DDAYANNA */
#define XK_Sinh_tha           0x1000dad  /* U+0DAD SINHALA TAYANNA */
#define XK_Sinh_thha          0x1000dae  /* U+0DAE SINHALA MAHA. TAYANNA */
#define XK_Sinh_dha           0x1000daf  /* U+0DAF SINHALA DAYANNA */
#define XK_Sinh_dhha          0x1000db0  /* U+0DB0 SINHALA MAHA. DAYANNA */
#define XK_Sinh_na            0x1000db1  /* U+0DB1 SINHALA DANTAJA NAYANNA */
#define XK_Sinh_ndha          0x1000db3  /* U+0DB3 SINHALA SANYAKA DAYANNA */
#define XK_Sinh_pa            0x1000db4  /* U+0DB4 SINHALA PAYANNA */
#define XK_Sinh_pha           0x1000db5  /* U+0DB5 SINHALA MAHA. PAYANNA */
#define XK_Sinh_ba            0x1000db6  /* U+0DB6 SINHALA BAYANNA */
#define XK_Sinh_bha           0x1000db7  /* U+0DB7 SINHALA MAHA. BAYANNA */
#define XK_Sinh_ma            0x1000db8  /* U+0DB8 SINHALA MAYANNA */
#define XK_Sinh_mba           0x1000db9  /* U+0DB9 SINHALA AMBA BAYANNA */
#define XK_Sinh_ya            0x1000dba  /* U+0DBA SINHALA YAYANNA */
#define XK_Sinh_ra            0x1000dbb  /* U+0DBB SINHALA RAYANNA */
#define XK_Sinh_la            0x1000dbd  /* U+0DBD SINHALA DANTAJA LAYANNA */
#define XK_Sinh_va            0x1000dc0  /* U+0DC0 SINHALA VAYANNA */
#define XK_Sinh_sha           0x1000dc1  /* U+0DC1 SINHALA TAALUJA SAYANNA */
#define XK_Sinh_ssha          0x1000dc2  /* U+0DC2 SINHALA MUURDHAJA SAYANNA */
#define XK_Sinh_sa            0x1000dc3  /* U+0DC3 SINHALA DANTAJA SAYANNA */
#define XK_Sinh_ha            0x1000dc4  /* U+0DC4 SINHALA HAYANNA */
#define XK_Sinh_lla           0x1000dc5  /* U+0DC5 SINHALA MUURDHAJA LAYANNA */
#define XK_Sinh_fa            0x1000dc6  /* U+0DC6 SINHALA FAYANNA */
#define XK_Sinh_al            0x1000dca  /* U+0DCA SINHALA AL-LAKUNA */
#define XK_Sinh_aa2           0x1000dcf  /* U+0DCF SINHALA AELA-PILLA */
#define XK_Sinh_ae2           0x1000dd0  /* U+0DD0 SINHALA AEDA-PILLA */
#define XK_Sinh_aee2          0x1000dd1  /* U+0DD1 SINHALA DIGA AEDA-PILLA */
#define XK_Sinh_i2            0x1000dd2  /* U+0DD2 SINHALA IS-PILLA */
#define XK_Sinh_ii2           0x1000dd3  /* U+0DD3 SINHALA DIGA IS-PILLA */
#define XK_Sinh_u2            0x1000dd4  /* U+0DD4 SINHALA PAA-PILLA */
#define XK_Sinh_uu2           0x1000dd6  /* U+0DD6 SINHALA DIGA PAA-PILLA */
#define XK_Sinh_ru2           0x1000dd8  /* U+0DD8 SINHALA GAETTA-PILLA */
#define XK_Sinh_e2            0x1000dd9  /* U+0DD9 SINHALA KOMBUVA */
#define XK_Sinh_ee2           0x1000dda  /* U+0DDA SINHALA DIGA KOMBUVA */
#define XK_Sinh_ai2           0x1000ddb  /* U+0DDB SINHALA KOMBU DEKA */
#define XK_Sinh_o2            0x1000ddc  /* U+0DDC SINHALA KOMBUVA HAA AELA-PILLA*/
#define XK_Sinh_oo2           0x1000ddd  /* U+0DDD SINHALA KOMBUVA HAA DIGA AELA-PILLA*/
#define XK_Sinh_au2           0x1000dde  /* U+0DDE SINHALA KOMBUVA HAA GAYANUKITTA */
#define XK_Sinh_lu2           0x1000ddf  /* U+0DDF SINHALA GAYANUKITTA */
#define XK_Sinh_ruu2          0x1000df2  /* U+0DF2 SINHALA DIGA GAETTA-PILLA */
#define XK_Sinh_luu2          0x1000df3  /* U+0DF3 SINHALA DIGA GAYANUKITTA */
#define XK_Sinh_kunddaliya    0x1000df4  /* U+0DF4 SINHALA KUNDDALIYA */
#endif /* XK_SINHALA */

/* Multimedia keys, defined same as on Linux
 * /usr/include/pkg/libxkbcommon/xkbcommon/xkbcommon-keysyms.h
 */

#ifndef TK_NO_DEPRECATED
#define XK_XF86AudioLowerVolume	0x1008FF11   /* Volume control down        */
#define XK_XF86AudioMute	0x1008FF12   /* Mute sound from the system */

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"

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
9
10
11
12
13
14
15




16
17








18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33







-
-
-
-
+
+
-
-
-
-
-
-
-
-



+
+
+
+
+
+







 * Copyright 2008-2009, Apple Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#if !defined(MAC_OSX_TK)
#   include <X11/Xlib.h>
#   define gcCacheSize 0
#include <X11/Xlib.h>
#if defined(MAC_OSX_TK)
#   define TkpInitGCCache(gc)
#   define TkpFreeGCCache(gc)
#   define TkpGetGCCache(gc)
#else
#   include <tkMacOSXInt.h>
#   include <X11/Xlib.h>
#   include <X11/X.h>
#   define gcCacheSize sizeof(TkpGCCache)
#endif


#define MAX_DASH_LIST_SIZE 10
typedef struct {
    XGCValues gc;
    char dash[MAX_DASH_LIST_SIZE];
} XGCValuesWithDash;

/*
 *----------------------------------------------------------------------
 *
 * AllocClipMask --
 *
 *	Static helper proc to allocate new or clear existing TkpClipMask.
 *
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
42
43
44
45
46
47
48




49
50
51
52
53
54
55







-
-
-
-








static TkpClipMask *AllocClipMask(GC gc) {
    TkpClipMask *clip_mask = (TkpClipMask*) gc->clip_mask;

    if (clip_mask == NULL) {
	clip_mask = (TkpClipMask *)ckalloc(sizeof(TkpClipMask));
	gc->clip_mask = (Pixmap) clip_mask;
#ifdef MAC_OSX_TK
    } else if (clip_mask->type == TKP_CLIP_REGION) {
	TkpReleaseRegion(clip_mask->value.region);
#endif
    }
    return clip_mask;
}

/*
 *----------------------------------------------------------------------
 *
72
73
74
75
76
77
78
79
80
81
82
83
84

85
86
87
88
89
90
91
64
65
66
67
68
69
70






71
72
73
74
75
76
77
78







-
-
-
-
-
-
+







 *	None.
 *
 *----------------------------------------------------------------------
 */

static void FreeClipMask(GC gc) {
    if (gc->clip_mask != None) {
#ifdef MAC_OSX_TK
	if (((TkpClipMask*) gc->clip_mask)->type == TKP_CLIP_REGION) {
	    TkpReleaseRegion(((TkpClipMask*) gc->clip_mask)->value.region);
	}
#endif
	ckfree((char *) gc->clip_mask);
	ckfree((char *)gc->clip_mask);
	gc->clip_mask = None;
    }
}

/*
 *----------------------------------------------------------------------
 *
115
116
117
118
119
120
121
122
123
124

125
126
127
128
129
130
131
102
103
104
105
106
107
108



109
110
111
112
113
114
115
116







-
-
-
+







    /*
     * 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.
     */

#define MAX_DASH_LIST_SIZE 10

    gp = (GC)ckalloc(sizeof(XGCValues) + MAX_DASH_LIST_SIZE + gcCacheSize);
    gp = (GC)ckalloc(sizeof(XGCValuesWithDash));
    if (!gp) {
	return NULL;
    }

#define InitField(name,maskbit,default) \
	(gp->name = (mask & (maskbit)) ? values->name : (default))

158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
143
144
145
146
147
148
149


150
151
152






















153
154
155
156
157
158
159







-
-



-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    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 ? (TkpGCCache*)(((char*) gc) + sizeof(XGCValues) +
	    MAX_DASH_LIST_SIZE) : NULL);
}
#endif

/*
 *----------------------------------------------------------------------
 *
 * XChangeGC --
 *
 *	Changes the GC components specified by valuemask for the specified GC.
 *
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
227
228
229
230
231
232
233

234
235
236
237
238
239
240







-







    Display *d,
    GC gc)
{
    (void)d;

    if (gc != NULL) {
	FreeClipMask(gc);
	TkpFreeGCCache(gc);
	ckfree(gc);
    }
    return Success;
}

/*
 *----------------------------------------------------------------------
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
452
453
454
455
456
457
458



459
460
461
462
463
464
465







-
-
-







    if (r == NULL) {
	Tcl_Panic("must not pass NULL to TkSetRegion for compatibility with X11; use XSetClipMask instead");
    } else {
	TkpClipMask *clip_mask = AllocClipMask(gc);

	clip_mask->type = TKP_CLIP_REGION;
	clip_mask->value.region = r;
#ifdef MAC_OSX_TK
	TkpRetainRegion(r);
#endif
    }
    return Success;
}

int
XSetClipMask(
    Display *display,
843
844
845
846
847
848
849
850

851
852
853
854
855
856
857
800
801
802
803
804
805
806

807
808
809
810
811
812
813
814







-
+







    (void)source_font;
    (void)mask_font;
    (void)source_char;
    (void)mask_char;
    (void)foreground_color;
    (void)background_color;

    return 1;
    return (Cursor) NULL;
}

XFontSet
XCreateFontSet(
    Display *display		/* display */,
    _Xconst char *base_font_name_list	/* base_font_name_list */,
    char ***missing_charset_list		/* missing_charset_list */,
966
967
968
969
970
971
972
973

974
975
976
977
978
979
980
981
923
924
925
926
927
928
929

930

931
932
933
934
935
936
937







-
+
-







XSetIMValues(
    XIM im /* im */, ...
) {
    (void)im;

    return NULL;
}



/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */